Theory WordDecl
section "Word Declarations"
theory WordDecl
imports Main "HOL-Library.Word"
begin
text ‹
This theory provides ‹len0› and ‹len› instantiations
for the most common used word sizes in the model (1,2,4,5,6,8,12,16,18,20,24,32,36).
The ‹len0› class defines lengths that range from 0 upwards,
whilst the ‹len› class caters for non-zero lengths.
Bit-operators like ‹<<›, ‹>>›, ‹and›, or ‹or›
require ‹a'::len› word instances,
while other word operations such @{term "ucast"}
(gets an integer from a word)
can be defined for ‹len0› words.
For each length ‹N›, we:
▸ declare a type ‹word_lengthN›;
▸ make it an instance of both length classes;
▸ and introduce a short type synonym ‹wordN›, and a suitable translation.
In essence, this theory is just a lot of boilerplate.
\newpage
›
section "Words of length 1"
typedecl word_length1
instantiation word_length1 :: len0
begin
definition
len1 [simp]: "len_of (x::word_length1 itself) ≡ 1"
instance ..
end
instantiation word_length1 :: len
begin
instance by intro_classes simp
end
type_synonym word1 = "word_length1 word"
translations (type) "word1" <= (type) "word_length1 word"
subsection "Words of length 1's constants"
definition ONE::"word1"
where
"ONE ≡ 1"
definition ZERO::"word1"
where
"ZERO ≡ 0"
section "Words of length 2"
typedecl word_length2
instantiation word_length2 :: len0
begin
definition
len2 [simp]: "len_of (x::word_length2 itself) ≡ 2"
instance ..
end
instantiation word_length2 :: len
begin
instance by intro_classes simp
end
type_synonym word2 = "word_length2 word"
translations (type) "word2" <= (type) "word_length2 word"
section "Words of length 3"
typedecl word_length3
instantiation word_length3 :: len0
begin
definition
len3 [simp]: "len_of (x::word_length3 itself) ≡ 3"
instance ..
end
instantiation word_length3 :: len
begin
instance by intro_classes simp
end
type_synonym word3 = "word_length3 word"
translations (type) "word3" <= (type) "word_length3 word"
section "Words of length 4"
typedecl word_length4
instantiation word_length4 :: len0
begin
definition
len4 [simp]: "len_of (x::word_length4 itself) ≡ 4"
instance ..
end
instantiation word_length4 :: len
begin
instance by intro_classes simp
end
type_synonym word4 = "word_length4 word"
translations (type) "word4" <= (type) "word_length4 word"
section "Words of length 5"
typedecl word_length5
instantiation word_length5 :: len0
begin
definition
len5 [simp]: "len_of (x::word_length5 itself) ≡ 5"
instance ..
end
instantiation word_length5 :: len
begin
instance by intro_classes simp
end
type_synonym word5 = "word_length5 word"
translations (type) "word5" <= (type) "word_length5 word"
section "Words of length 6"
typedecl word_length6
instantiation word_length6 :: len0
begin
definition
len6 [simp]: "len_of (x::word_length6 itself) ≡ 6"
instance ..
end
instantiation word_length6 :: len
begin
instance by intro_classes simp
end
type_synonym word6 = "word_length6 word"
translations (type) "word6" <= (type) "word_length6 word"
section "Words of length 6"
typedecl word_length7
instantiation word_length7 :: len0
begin
definition
len7 [simp]: "len_of (x::word_length7 itself) ≡ 7"
instance ..
end
instantiation word_length7 :: len
begin
instance by intro_classes simp
end
type_synonym word7 = "word_length7 word"
translations (type) "word7" <= (type) "word_length7 word"
section "Words of length 8"
typedecl word_length8
instantiation word_length8 :: len0
begin
definition
len8 [simp]: "len_of (x::word_length8 itself) ≡ 8"
instance ..
end
instantiation word_length8 :: len
begin
instance by intro_classes simp
end
type_synonym word8 = "word_length8 word"
translations (type) "word8" <= (type) "word_length8 word"
section "Words of length 9"
typedecl word_length9
instantiation word_length9 :: len0
begin
definition
len9 [simp]: "len_of (x::word_length9 itself) ≡ 9"
instance ..
end
instantiation word_length9 :: len
begin
instance by intro_classes simp
end
type_synonym word9 = "word_length9 word"
translations (type) "word9" <= (type) "word_length9 word"
section "Words of length 10"
typedecl word_length10
instantiation word_length10 :: len0
begin
definition
len10 [simp]: "len_of (x::word_length10 itself) ≡ 10"
instance ..
end
instantiation word_length10 :: len
begin
instance by intro_classes simp
end
type_synonym word10 = "word_length10 word"
translations (type) "word10" <= (type) "word_length10 word"
section "Words of length 12"
typedecl word_length12
instantiation word_length12 :: len0
begin
definition
len12 [simp]: "len_of (x::word_length12 itself) ≡ 12"
instance ..
end
instantiation word_length12 :: len
begin
instance by intro_classes simp
end
type_synonym word12 = "word_length12 word"
translations (type) "word12" <= (type) "word_length12 word"
section "Words of length 13"
typedecl word_length13
instantiation word_length13 :: len0
begin
definition
len13 [simp]: "len_of (x::word_length13 itself) ≡ 13"
instance ..
end
instantiation word_length13 :: len
begin
instance by intro_classes simp
end
type_synonym word13 = "word_length13 word"
translations (type) "word13" <= (type) "word_length13 word"
section "Words of length 16"
typedecl word_length16
instantiation word_length16 :: len0
begin
definition
len16 [simp]: "len_of (x::word_length16 itself) ≡ 16"
instance ..
end
instantiation word_length16 :: len
begin
instance by intro_classes simp
end
type_synonym word16 = "word_length16 word"
translations (type) "word16" <= (type) "word_length16 word"
section "Words of length 18"
typedecl word_length18
instantiation word_length18 :: len0
begin
definition
len18 [simp]: "len_of (x::word_length18 itself) ≡ 18"
instance ..
end
instantiation word_length18 :: len
begin
instance by intro_classes simp
end
type_synonym word18 = "word_length18 word"
translations (type) "word18" <= (type) "word_length18 word"
section "Words of length 20"
typedecl word_length20
instantiation word_length20 :: len0
begin
definition
len20 [simp]: "len_of (x::word_length20 itself) ≡ 20"
instance ..
end
instantiation word_length20 :: len
begin
instance by intro_classes simp
end
type_synonym word20 = "word_length20 word"
translations (type) "word20" <= (type) "word_length20 word"
section "Words of length 22"
typedecl word_length22
instantiation word_length22 :: len0
begin
definition
len22 [simp]: "len_of (x::word_length22 itself) ≡ 22"
instance ..
end
instantiation word_length22 :: len
begin
instance by intro_classes simp
end
type_synonym word22 = "word_length22 word"
translations (type) "word22" <= (type) "word_length22 word"
section "Words of length 24"
typedecl word_length24
instantiation word_length24 :: len0
begin
definition
len24 [simp]: "len_of (x::word_length24 itself) ≡ 24"
instance ..
end
instantiation word_length24 :: len
begin
instance by intro_classes simp
end
type_synonym word24 = "word_length24 word"
translations (type) "word24" <= (type) "word_length24 word"
section "Words of length 30"
typedecl word_length30
instantiation word_length30 :: len0
begin
definition
len30 [simp]: "len_of (x::word_length30 itself) ≡ 30"
instance ..
end
instantiation word_length30 :: len
begin
instance by intro_classes simp
end
type_synonym word30 = "word_length30 word"
translations (type) "word30" <= (type) "word_length30 word"
section "Words of length 30"
typedecl word_length31
instantiation word_length31 :: len0
begin
definition
len31 [simp]: "len_of (x::word_length31 itself) ≡ 31"
instance ..
end
instantiation word_length31 :: len
begin
instance by intro_classes simp
end
type_synonym word31 = "word_length31 word"
translations (type) "word31" <= (type) "word_length31 word"
section "Words of length 32"
typedecl word_length32
instantiation word_length32 :: len0
begin
definition
len32 [simp]: "len_of (x::word_length32 itself) ≡ 32"
instance ..
end
instantiation word_length32 :: len
begin
instance by intro_classes simp
end
type_synonym word32 = "word_length32 word"
translations (type) "word32" <= (type) "word_length32 word"
section "Words of length 33"
typedecl word_length33
instantiation word_length33 :: len0
begin
definition
len33 [simp]: "len_of (x::word_length33 itself) ≡ 33"
instance ..
end
instantiation word_length33 :: len
begin
instance by intro_classes simp
end
type_synonym word33 = "word_length33 word"
translations (type) "word33" <= (type) "word_length33 word"
section "Words of length 36"
typedecl word_length36
instantiation word_length36 :: len0
begin
definition
len36 [simp]: "len_of (x::word_length36 itself) ≡ 36"
instance ..
end
instantiation word_length36 :: len
begin
instance by intro_classes simp
end
type_synonym word36 = "word_length36 word"
translations (type) "word36" <= (type) "word_length36 word"
section "Words of length 64"
typedecl word_length64
instantiation word_length64 :: len0
begin
definition
len64 [simp]: "len_of (x::word_length64 itself) ≡ 64"
instance ..
end
instantiation word_length64 :: len
begin
instance by intro_classes simp
end
type_synonym word64 = "word_length64 word"
translations (type) "word64" <= (type) "word_length64 word"
end
Theory Sparc_Types
section ‹SPARC V8 architecture CPU model›
theory Sparc_Types
imports Main "../lib/WordDecl" "Word_Lib.Traditional_Infix_Syntax"
begin
text ‹The following type definitions are taken from David Sanan's
definitions for SPARC machines.›
type_synonym machine_word = word32
type_synonym byte = word8
type_synonym phys_address = word36
type_synonym virtua_address = word32
type_synonym page_address = word24
type_synonym offset = word12
type_synonym table_entry = word8
definition page_size :: "word32" where "page_size ≡ 4096"
type_synonym virtua_page_address = word20
type_synonym context_type = word8
type_synonym word_length_t1 = word_length8
type_synonym word_length_t2 = word_length6
type_synonym word_length_t3 = word_length6
type_synonym word_length_offset = word_length12
type_synonym word_length_page = word_length24
type_synonym word_length_phys_address = word_length36
type_synonym word_length_virtua_address = word_length32
type_synonym word_length_entry_type = word_length2
type_synonym word_length_machine_word = word_length32
definition length_machine_word :: "nat"
where "length_machine_word ≡ LENGTH(word_length_machine_word)"
text_raw ‹\newpage›
section ‹CPU Register Definitions›
text‹
The definitions below come from the SPARC Architecture Manual, Version 8.
The LEON3 processor has been certified SPARC V8 conformant (2005).
›
definition leon3khz ::"word32"
where
"leon3khz ≡ 33000"
text ‹The following type definitions for MMU is taken from
David Sanan's definitions for MMU.›
text‹
The definitions below come from the UT699 LEON 3FT/SPARC V8 Microprocessor Functional Manual,
Aeroflex, June 20, 2012, p35.
›
datatype MMU_register
= CR
| CTP
| CNR
| FTSR
| FAR
lemma MMU_register_induct:
"P CR ⟹ P CTP ⟹ P CNR ⟹ P FTSR ⟹ P FAR
⟹ P x"
by (cases x) auto
lemma UNIV_MMU_register [no_atp]: "UNIV = {CR, CTP, CNR, FTSR, FAR}"
apply (safe)
apply (case_tac x)
apply (auto intro:MMU_register_induct)
done
instantiation MMU_register :: enum begin
definition "enum_MMU_register = [ CR, CTP, CNR, FTSR, FAR ]"
definition
"enum_all_MMU_register P ⟷ P CR ∧ P CTP ∧ P CNR ∧ P FTSR ∧ P FAR "
definition
"enum_ex_MMU_register P ⟷ P CR ∨ P CTP ∨ P CNR ∨ P FTSR ∨ P FAR"
instance proof
qed (simp_all only: enum_MMU_register_def enum_all_MMU_register_def
enum_ex_MMU_register_def UNIV_MMU_register, simp_all)
end
type_synonym MMU_context = "MMU_register ⇒ machine_word"
text ‹‹PTE_flags› is the last 8 bits of a PTE. See page 242 of SPARCv8 manual.
▪ C - bit 7
▪ M - bit 6,
▪ R - bit 5
▪ ACC - bit 4~2
▪ ET - bit 1~0.›
type_synonym PTE_flags = word8
text ‹
@{term CPU_register} datatype is an enumeration with the CPU registers defined in the SPARC V8
architecture.
›
datatype CPU_register =
PSR
| WIM
| TBR
| Y
| PC
| nPC
| DTQ
| FSR
| FQ
| CSR
| CQ
| ASR "word5"
text ‹The following two functions are dummies since we will not use
ASRs. Future formalisation may add more details to this.›
definition privileged_ASR :: "word5 ⇒ bool"
where
"privileged_ASR r ≡ False
"
definition illegal_instruction_ASR :: "word5 ⇒ bool"
where
"illegal_instruction_ASR r ≡ False
"
definition get_tt :: "word32 ⇒ word8"
where
"get_tt tbr ≡
ucast (((AND) tbr 0b00000000000000000000111111110000) >> 4)
"
text ‹Write the tt field of the TBR register.
Return the new value of TBR.›
definition write_tt :: "word8 ⇒ word32 ⇒ word32"
where
"write_tt new_tt_val tbr_val ≡
let tmp = (AND) tbr_val 0b111111111111111111111000000001111 in
(OR) tmp (((ucast new_tt_val)::word32) << 4)
"
text ‹Get the nth bit of WIM. This equals ((AND) WIM $2^n$).
N.B. the first bit of WIM is the 0th bit.›
definition get_WIM_bit :: "nat ⇒ word32 ⇒ word1"
where
"get_WIM_bit n wim ≡
let mask = ((ucast (0b1::word1))::word32) << n in
ucast (((AND) mask wim) >> n)
"
definition get_CWP :: "word32 ⇒ word5"
where
"get_CWP psr ≡
ucast ((AND) psr 0b00000000000000000000000000011111)
"
definition get_ET :: "word32 ⇒ word1"
where
"get_ET psr ≡
ucast (((AND) psr 0b00000000000000000000000000100000) >> 5)
"
definition get_PIL :: "word32 ⇒ word4"
where
"get_PIL psr ≡
ucast (((AND) psr 0b00000000000000000000111100000000) >> 8)
"
definition get_PS :: "word32 ⇒ word1"
where
"get_PS psr ≡
ucast (((AND) psr 0b00000000000000000000000001000000) >> 6)
"
definition get_S :: "word32 ⇒ word1"
where
"get_S psr ≡
if ((AND) psr (0b00000000000000000000000010000000::word32)) = 0 then 0
else 1
"
definition get_icc_N :: "word32 ⇒ word1"
where
"get_icc_N psr ≡
ucast (((AND) psr 0b00000000100000000000000000000000) >> 23)
"
definition get_icc_Z :: "word32 ⇒ word1"
where
"get_icc_Z psr ≡
ucast (((AND) psr 0b00000000010000000000000000000000) >> 22)
"
definition get_icc_V :: "word32 ⇒ word1"
where
"get_icc_V psr ≡
ucast (((AND) psr 0b00000000001000000000000000000000) >> 21)
"
definition get_icc_C :: "word32 ⇒ word1"
where
"get_icc_C psr ≡
ucast (((AND) psr 0b00000000000100000000000000000000) >> 20)
"
definition update_S :: "word1 ⇒ word32 ⇒ word32"
where
"update_S s_val psr_val ≡
let tmp0 = (AND) psr_val 0b11111111111111111111111101111111 in
(OR) tmp0 (((ucast s_val)::word32) << 7)
"
text ‹Update the CWP field of PSR.
Return the new value of PSR.›
definition update_CWP :: "word5 ⇒ word32 ⇒ word32"
where
"update_CWP cwp_val psr_val ≡
let tmp0 = (AND) psr_val (0b11111111111111111111111111100000::word32);
s_val = ((ucast (get_S psr_val))::word1)
in
if s_val = 0 then
(AND) ((OR) tmp0 ((ucast cwp_val)::word32)) (0b11111111111111111111111101111111::word32)
else
(OR) ((OR) tmp0 ((ucast cwp_val)::word32)) (0b00000000000000000000000010000000::word32)
"
text ‹Update the the ET, CWP, and S fields of PSR.
Return the new value of PSR.›
definition update_PSR_rett :: "word5 ⇒ word1 ⇒ word1 ⇒ word32 ⇒ word32"
where
"update_PSR_rett cwp_val et_val s_val psr_val ≡
let tmp0 = (AND) psr_val 0b11111111111111111111111101000000;
tmp1 = (OR) tmp0 ((ucast cwp_val)::word32);
tmp2 = (OR) tmp1 (((ucast et_val)::word32) << 5);
tmp3 = (OR) tmp2 (((ucast s_val)::word32) << 7)
in
tmp3
"
definition update_PSR_exe_trap :: "word5 ⇒ word1 ⇒ word1 ⇒ word32 ⇒ word32"
where
"update_PSR_exe_trap cwp_val et_val ps_val psr_val ≡
let tmp0 = (AND) psr_val 0b11111111111111111111111110000000;
tmp1 = (OR) tmp0 ((ucast cwp_val)::word32);
tmp2 = (OR) tmp1 (((ucast et_val)::word32) << 5);
tmp3 = (OR) tmp2 (((ucast ps_val)::word32) << 6)
in
tmp3
"
text ‹Update the N, Z, V, C fields of PSR.
Return the new value of PSR.›
definition update_PSR_icc :: "word1 ⇒ word1 ⇒ word1 ⇒ word1 ⇒ word32 ⇒ word32"
where
"update_PSR_icc n_val z_val v_val c_val psr_val ≡
let
n_val_32 = if n_val = 0 then 0
else (0b00000000100000000000000000000000::word32);
z_val_32 = if z_val = 0 then 0
else (0b00000000010000000000000000000000::word32);
v_val_32 = if v_val = 0 then 0
else (0b00000000001000000000000000000000::word32);
c_val_32 = if c_val = 0 then 0
else (0b00000000000100000000000000000000::word32);
tmp0 = (AND) psr_val (0b11111111000011111111111111111111::word32);
tmp1 = (OR) tmp0 n_val_32;
tmp2 = (OR) tmp1 z_val_32;
tmp3 = (OR) tmp2 v_val_32;
tmp4 = (OR) tmp3 c_val_32
in
tmp4
"
text ‹Update the ET, PIL fields of PSR.
Return the new value of PSR.›
definition update_PSR_et_pil :: "word1 ⇒ word4 ⇒ word32 ⇒ word32"
where
"update_PSR_et_pil et pil psr_val ≡
let tmp0 = (AND) psr_val 0b111111111111111111111000011011111;
tmp1 = (OR) tmp0 (((ucast et)::word32) << 5);
tmp2 = (OR) tmp1 (((ucast pil)::word32) << 8)
in
tmp2
"
text ‹
SPARC V8 architecture is organized in windows of 32 user registers.
The data stored in a register is defined as a 32 bits word @{term reg_type}:
›
type_synonym reg_type = "word32"
text ‹
The access to the value of a CPU register of type @{term CPU_register} is
defined by a total function @{term cpu_context}
›
type_synonym cpu_context = "CPU_register ⇒ reg_type"
text ‹
User registers are defined with the type @{term user_reg} represented by a 5 bits word.
›
type_synonym user_reg_type = "word5"
definition PSR_S ::"reg_type"
where "PSR_S ≡ 6"
text ‹
Each window context is defined by a total function @{term window_context} from @{term user_register}
to @{term reg_type} (32 bits word storing the actual value of the register).
›
type_synonym window_context = "user_reg_type ⇒ reg_type"
text ‹
The number of windows is implementation dependent.
The LEON architecture is composed of 16 different windows (a 4 bits word).
›
definition NWINDOWS :: "int"
where "NWINDOWS ≡ 8"
text ‹Maximum number of windows is 32 in SPARCv8.›
type_synonym ('a) window_size = "'a word"
text ‹
Finally the user context is defined by another total function @{term user_context} from
@{term window_size} to @{term window_context}. That is, the user context is a function taking as
argument a register set window and a register within that window, and it returns the value stored
in that user register.
›
type_synonym ('a) user_context = "('a) window_size ⇒ window_context"
datatype sys_reg =
CCR
|ICCR
|DCCR
type_synonym sys_context = "sys_reg ⇒ reg_type"
text‹
The memory model is defined by a total function from 32 bits words to 8 bits words
›
type_synonym asi_type = "word8"
text ‹
The memory is defined as a function from page address to page, which is also defined
as a function from physical address to @{term "machine_word"}
›
type_synonym mem_val_type = "word8"
type_synonym mem_context = "asi_type ⇒ phys_address ⇒ mem_val_type option"
type_synonym cache_tag = "word20"
type_synonym cache_line_size = "word12"
type_synonym cache_type = "(cache_tag × cache_line_size)"
type_synonym cache_context = "cache_type ⇒ mem_val_type option"
text ‹The delayed-write pool generated from write state register instructions.›
type_synonym delayed_write_pool = "(int × reg_type × CPU_register) list"
definition DELAYNUM :: "int"
where "DELAYNUM ≡ 0"
text ‹Convert a set to a list.›
definition list_of_set :: "'a set ⇒ 'a list"
where "list_of_set s = (SOME l. set l = s)"
lemma set_list_of_set: "finite s ⟹ set (list_of_set s) = s"
unfolding list_of_set_def
by (metis (mono_tags) finite_list some_eq_ex)
type_synonym ANNUL = "bool"
type_synonym RESET_TRAP = "bool"
type_synonym EXECUTE_MODE = "bool"
type_synonym RESET_MODE = "bool"
type_synonym ERROR_MODE = "bool"
type_synonym TICC_TRAP_TYPE = "word7"
type_synonym INTERRUPT_LEVEL = "word3"
type_synonym STORE_BARRIER_PENDING = "bool"
text ‹The processor asserts this signal to ensure that the
memory system will not process another SWAP or
LDSTUB operation to the same memory byte.›
type_synonym pb_block_ldst_byte = "virtua_address ⇒ bool"
text‹The processor asserts this signal to ensure that the
memory system will not process another SWAP or
LDSTUB operation to the same memory word.›
type_synonym pb_block_ldst_word = "virtua_address ⇒ bool"
record sparc_state_var =
annul:: ANNUL
resett:: RESET_TRAP
exe:: EXECUTE_MODE
reset:: RESET_MODE
err:: ERROR_MODE
ticc:: TICC_TRAP_TYPE
itrpt_lvl:: INTERRUPT_LEVEL
st_bar:: STORE_BARRIER_PENDING
atm_ldst_byte:: pb_block_ldst_byte
atm_ldst_word:: pb_block_ldst_word
definition get_annul :: "sparc_state_var ⇒ bool"
where "get_annul v ≡ annul v"
definition get_reset_trap :: "sparc_state_var ⇒ bool"
where "get_reset_trap v ≡ resett v"
definition get_exe_mode :: "sparc_state_var ⇒ bool"
where "get_exe_mode v ≡ exe v"
definition get_reset_mode :: "sparc_state_var ⇒ bool"
where "get_reset_mode v ≡ reset v"
definition get_err_mode :: "sparc_state_var ⇒ bool"
where "get_err_mode v ≡ err v"
definition get_ticc_trap_type :: "sparc_state_var ⇒ word7"
where "get_ticc_trap_type v ≡ ticc v"
definition get_interrupt_level :: "sparc_state_var ⇒ word3"
where "get_interrupt_level v ≡ itrpt_lvl v"
definition get_store_barrier_pending :: "sparc_state_var ⇒ bool"
where "get_store_barrier_pending v ≡ st_bar v"
definition write_annul :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_annul b v ≡ v⦇annul := b⦈"
definition write_reset_trap :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_reset_trap b v ≡ v⦇resett := b⦈"
definition write_exe_mode :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_exe_mode b v ≡ v⦇exe := b⦈"
definition write_reset_mode :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_reset_mode b v ≡ v⦇reset := b⦈"
definition write_err_mode :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_err_mode b v ≡ v⦇err := b⦈"
definition write_ticc_trap_type :: "word7 ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_ticc_trap_type w v ≡ v⦇ticc := w⦈"
definition write_interrupt_level :: "word3 ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_interrupt_level w v ≡ v⦇itrpt_lvl := w⦈"
definition write_store_barrier_pending :: "bool ⇒ sparc_state_var ⇒ sparc_state_var"
where "write_store_barrier_pending b v ≡ v⦇st_bar := b⦈"
text ‹Given a word7 value, find the highest bit,
and fill the left bits to be the highest bit.›
definition sign_ext7::"word7 ⇒ word32"
where
"sign_ext7 w ≡
let highest_bit = ((AND) w 0b1000000) >> 6 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111111111111111111110000000
"
definition zero_ext8 :: "word8 ⇒ word32"
where
"zero_ext8 w ≡ (ucast w)::word32
"
text ‹Given a word8 value, find the highest bit,
and fill the left bits to be the highest bit.›
definition sign_ext8::"word8 ⇒ word32"
where
"sign_ext8 w ≡
let highest_bit = ((AND) w 0b10000000) >> 7 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111111111111111111100000000
"
text ‹Given a word13 value, find the highest bit,
and fill the left bits to be the highest bit.›
definition sign_ext13::"word13 ⇒ word32"
where
"sign_ext13 w ≡
let highest_bit = ((AND) w 0b1000000000000) >> 12 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111111111111110000000000000
"
definition zero_ext16 :: "word16 ⇒ word32"
where
"zero_ext16 w ≡ (ucast w)::word32
"
text ‹Given a word16 value, find the highest bit,
and fill the left bits to be the highest bit.›
definition sign_ext16::"word16 ⇒ word32"
where
"sign_ext16 w ≡
let highest_bit = ((AND) w 0b1000000000000000) >> 15 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111111111110000000000000000
"
text ‹Given a word22 value, find the highest bit,
and fill the left bits to tbe the highest bit.›
definition sign_ext22::"word22 ⇒ word32"
where
"sign_ext22 w ≡
let highest_bit = ((AND) w 0b1000000000000000000000) >> 21 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111110000000000000000000000
"
text ‹Given a word24 value, find the highest bit,
and fill the left bits to tbe the highest bit.›
definition sign_ext24::"word24 ⇒ word32"
where
"sign_ext24 w ≡
let highest_bit = ((AND) w 0b100000000000000000000000) >> 23 in
if highest_bit = 0 then
(ucast w)::word32
else (OR) ((ucast w)::word32) 0b11111111000000000000000000000000
"
text‹
Operations to be defined.
The SPARC V8 architecture is composed of the following set of instructions:
▪ Load Integer Instructions
▪ Load Floating-point Instructions
▪ Load Coprocessor Instructions
▪ Store Integer Instructions
▪ Store Floating-point Instructions
▪ Store Coprocessor Instructions
▪ Atomic Load-Store Unsigned Byte Instructions
▪ SWAP Register With Memory Instruction
▪ SETHI Instructions
▪ NOP Instruction
▪ Logical Instructions
▪ Shift Instructions
▪ Add Instructions
▪ Tagged Add Instructions
▪ Subtract Instructions
▪ Tagged Subtract Instructions
▪ Multiply Step Instruction
▪ Multiply Instructions
▪ Divide Instructions
▪ SAVE and RESTORE Instructions
▪ Branch on Integer Condition Codes Instructions
▪ Branch on Floating-point Condition Codes Instructions
▪ Branch on Coprocessor Condition Codes Instructions
▪ Call and Link Instruction
▪ Jump and Link Instruction
▪ Return from Trap Instruction
▪ Trap on Integer Condition Codes Instructions
▪ Read State Register Instructions
▪ Write State Register Instructions
▪ STBAR Instruction
▪ Unimplemented Instruction
▪ Flush Instruction Memory
▪ Floating-point Operate (FPop) Instructions
▪ Convert Integer to Floating point Instructions
▪ Convert Floating point to Integer Instructions
▪ Convert Between Floating-point Formats Instructions
▪ Floating-point Move Instructions
▪ Floating-point Square Root Instructions
▪ Floating-point Add and Subtract Instructions
▪ Floating-point Multiply and Divide Instructions
▪ Floating-point Compare Instructions
▪ Coprocessor Operate Instructions
›
text ‹The CALL instruction.›
datatype call_type = CALL
text ‹The SETHI instruction.›
datatype sethi_type = SETHI
text ‹The NOP instruction.›
datatype nop_type = NOP
text ‹The Branch on integer condition codes instructions.›
datatype bicc_type =
BE
| BNE
| BGU
| BLE
| BL
| BGE
| BNEG
| BG
| BCS
| BLEU
| BCC
| BA
| BN
| BPOS
| BVC
| BVS
text ‹Memory instructions. That is, load and store.›
datatype load_store_type =
LDSB
| LDUB
| LDUBA
| LDUH
| LD
| LDA
| LDD
| STB
| STH
| ST
| STA
| STD
| LDSBA
| LDSH
| LDSHA
| LDUHA
| LDDA
| STBA
| STHA
| STDA
| LDSTUB
| LDSTUBA
| SWAP
| SWAPA
| FLUSH
| STBAR
text ‹Arithmetic instructions.›
datatype arith_type =
ADD
| ADDcc
| ADDX
| SUB
| SUBcc
| SUBX
| UMUL
| SMUL
| SMULcc
| UDIV
| UDIVcc
| SDIV
| ADDXcc
| TADDcc
| TADDccTV
| SUBXcc
| TSUBcc
| TSUBccTV
| MULScc
| UMULcc
| SDIVcc
text ‹Logical instructions.›
datatype logic_type =
ANDs
| ANDcc
| ANDN
| ANDNcc
| ORs
| ORcc
| ORN
| XORs
| XNOR
| ORNcc
| XORcc
| XNORcc
text ‹Shift instructions.›
datatype shift_type =
SLL
| SRL
| SRA
text ‹Other Control-transfer instructions.›
datatype ctrl_type =
JMPL
| RETT
| SAVE
| RESTORE
text ‹Access state registers instructions.›
datatype sreg_type =
RDASR
| RDY
| RDPSR
| RDWIM
| RDTBR
| WRASR
| WRY
| WRPSR
| WRWIM
| WRTBR
text ‹Unimplemented instruction.›
datatype uimp_type = UNIMP
text ‹Trap on integer condition code instructions.›
datatype ticc_type =
TA
| TN
| TNE
| TE
| TG
| TLE
| TGE
| TL
| TGU
| TLEU
| TCC
| TCS
| TPOS
| TNEG
| TVC
| TVS
datatype sparc_operation =
call_type call_type
| sethi_type sethi_type
| nop_type nop_type
| bicc_type bicc_type
| load_store_type load_store_type
| arith_type arith_type
| logic_type logic_type
| shift_type shift_type
| ctrl_type ctrl_type
| sreg_type sreg_type
| uimp_type uimp_type
| ticc_type ticc_type
datatype Trap =
reset
|data_store_error
|instruction_access_MMU_miss
|instruction_access_error
|r_register_access_error
|instruction_access_exception
|privileged_instruction
|illegal_instruction
|unimplemented_FLUSH
|watchpoint_detected
|fp_disabled
|cp_disabled
|window_overflow
|window_underflow
|mem_address_not_aligned
|fp_exception
|cp_exception
|data_access_error
|data_access_MMU_miss
|data_access_exception
|tag_overflow
|division_by_zero
|trap_instruction
|interrupt_level_n
datatype Exception =
invalid_cond_f2
|invalid_op2_f2
|illegal_instruction2
|invalid_op3_f3_op11
|case_impossible
|invalid_op3_f3_op10
|invalid_op_f3
|unsupported_instruction
|fetch_instruction_error
|invalid_trap_cond
end
Theory Lib
theory Lib
imports Main
begin
lemma hd_map_simp:
"b ≠ [] ⟹ hd (map a b) = a (hd b)"
by (rule hd_map)
lemma tl_map_simp:
"tl (map a b) = map a (tl b)"
by (induct b,auto)
lemma Collect_eq:
"{x. P x} = {x. Q x} ⟷ (∀x. P x = Q x)"
by (rule iffI) auto
lemma iff_impI: "⟦P ⟹ Q = R⟧ ⟹ (P ⟶ Q) = (P ⟶ R)" by blast
definition
fun_app :: "('a ⇒ 'b) ⇒ 'a ⇒ 'b" (infixr "$" 10) where
"f $ x ≡ f x"
declare fun_app_def [iff]
lemma fun_app_cong[fundef_cong]:
"⟦ f x = f' x' ⟧ ⟹ (f $ x) = (f' $ x')"
by simp
lemma fun_app_apply_cong[fundef_cong]:
"f x y = f' x' y' ⟹ (f $ x) y = (f' $ x') y'"
by simp
lemma if_apply_cong[fundef_cong]:
"⟦ P = P'; x = x'; P' ⟹ f x' = f' x'; ¬ P' ⟹ g x' = g' x' ⟧
⟹ (if P then f else g) x = (if P' then f' else g') x'"
by simp
abbreviation (input) split :: "('a ⇒ 'b ⇒ 'c) ⇒ 'a × 'b ⇒ 'c" where
"split ≡ case_prod"
lemma split_apply_cong[fundef_cong]:
"⟦ f (fst p) (snd p) s = f' (fst p') (snd p') s' ⟧ ⟹ split f p s = split f' p' s'"
by (simp add: split_def)
definition
pred_conj :: "('a ⇒ bool) ⇒ ('a ⇒ bool) ⇒ ('a ⇒ bool)" (infixl "and" 35)
where
"pred_conj P Q ≡ λx. P x ∧ Q x"
definition
pred_disj :: "('a ⇒ bool) ⇒ ('a ⇒ bool) ⇒ ('a ⇒ bool)" (infixl "or" 30)
where
"pred_disj P Q ≡ λx. P x ∨ Q x"
definition
pred_neg :: "('a ⇒ bool) ⇒ ('a ⇒ bool)" ("not _" [40] 40)
where
"pred_neg P ≡ λx. ¬ P x"
definition "K ≡ λx y. x"
definition
zipWith :: "('a ⇒ 'b ⇒ 'c) ⇒ 'a list ⇒ 'b list ⇒ 'c list" where
"zipWith f xs ys ≡ map (split f) (zip xs ys)"
primrec
delete :: "'a ⇒ 'a list ⇒ 'a list"
where
"delete y [] = []"
| "delete y (x#xs) = (if y=x then xs else x # delete y xs)"
primrec
find :: "('a ⇒ bool) ⇒ 'a list ⇒ 'a option"
where
"find f [] = None"
| "find f (x # xs) = (if f x then Some x else find f xs)"
definition
"swp f ≡ λx y. f y x"
primrec (nonexhaustive)
theRight :: "'a + 'b ⇒ 'b" where
"theRight (Inr x) = x"
primrec (nonexhaustive)
theLeft :: "'a + 'b ⇒ 'a" where
"theLeft (Inl x) = x"
definition
"isLeft x ≡ (∃y. x = Inl y)"
definition
"isRight x ≡ (∃y. x = Inr y)"
definition
"const x ≡ λy. x"
lemma tranclD2:
"(x, y) ∈ R⇧+ ⟹ ∃z. (x, z) ∈ R⇧* ∧ (z, y) ∈ R"
by (erule tranclE) auto
lemma linorder_min_same1 [simp]:
"(min y x = y) = (y ≤ (x::'a::linorder))"
by (auto simp: min_def linorder_not_less)
lemma linorder_min_same2 [simp]:
"(min x y = y) = (y ≤ (x::'a::linorder))"
by (auto simp: min_def linorder_not_le)
text ‹A combinator for pairing up well-formed relations.
The divisor function splits the population in halves,
with the True half greater than the False half, and
the supplied relations control the order within the halves.›
definition
wf_sum :: "('a ⇒ bool) ⇒ ('a × 'a) set ⇒ ('a × 'a) set ⇒ ('a × 'a) set"
where
"wf_sum divisor r r' ≡
({(x, y). ¬ divisor x ∧ ¬ divisor y} ∩ r')
∪ {(x, y). ¬ divisor x ∧ divisor y}
∪ ({(x, y). divisor x ∧ divisor y} ∩ r)"
lemma wf_sum_wf:
"⟦ wf r; wf r' ⟧ ⟹ wf (wf_sum divisor r r')"
apply (simp add: wf_sum_def)
apply (rule wf_Un)+
apply (erule wf_Int2)
apply (rule wf_subset
[where r="measure (λx. If (divisor x) 1 0)"])
apply simp
apply clarsimp
apply blast
apply (erule wf_Int2)
apply blast
done
abbreviation(input)
"option_map == map_option"
lemmas option_map_def = map_option_case
lemma False_implies_equals [simp]:
"((False ⟹ P) ⟹ PROP Q) ≡ PROP Q"
apply (rule equal_intr_rule)
apply (erule meta_mp)
apply simp
apply simp
done
lemma split_paired_Ball:
"(∀x ∈ A. P x) = (∀x y. (x,y) ∈ A ⟶ P (x,y))"
by auto
lemma split_paired_Bex:
"(∃x ∈ A. P x) = (∃x y. (x,y) ∈ A ∧ P (x,y))"
by auto
end
Theory DetMonad
theory DetMonad
imports "../Lib"
begin
text ‹
\label{c:monads}
State monads are used extensively in the seL4 specification. They are
defined below.
›
section "The Monad"
text ‹
The basic type of the deterministic state monad with failure is
very similar to the normal state monad. Instead of a pair consisting
of result and new state, we return a pair coupled with
a failure flag. The flag is @{const True} if the computation have failed.
Conversely, if the flag is @{const False}, the computation resulting in
the returned result have succeeded.›
type_synonym ('s,'a) det_monad = "'s ⇒ ('a × 's) × bool"
text ‹
The definition of fundamental monad functions ‹return› and
‹bind›. The monad function ‹return x› does not change
the state, does not fail, and returns ‹x›.
›
definition
return :: "'a ⇒ ('s,'a) det_monad" where
"return a ≡ λs. ((a,s),False)"
text ‹
The monad function ‹bind f g›, also written ‹f >>= g›,
is the execution of @{term f} followed by the execution of ‹g›.
The function ‹g› takes the result value \emph{and} the result
state of ‹f› as parameter. The definition says that the result of
the combined operation is the result which is created
by ‹g› applied to the result of ‹f›. The combined
operation may have failed, if ‹f› may have failed or ‹g› may
have failed on the result of ‹f›.
›
text ‹
David Sanan and Zhe Hou: The original definition of bind is very inefficient
when converted to executable code. Here we change it to a more efficient
version for execution. The idea remains the same.
›
definition "h1 f s = f s"
definition "h2 g fs = (let (a,b) = fst (fs) in g a b)"
definition bind:: "('s, 'a) det_monad ⇒ ('a ⇒ ('s, 'b) det_monad) ⇒
('s, 'b) det_monad" (infixl ">>=" 60)
where
"bind f g ≡ λs. (
let fs = h1 f s;
v = h2 g fs
in
(fst v, (snd v ∨ snd fs)))"
text ‹
Sometimes it is convenient to write ‹bind› in reverse order.
›
abbreviation(input)
bind_rev :: "('c ⇒ ('a, 'b) det_monad) ⇒ ('a, 'c) det_monad ⇒
('a, 'b) det_monad" (infixl "=<<" 60) where
"g =<< f ≡ f >>= g"
text ‹
The basic accessor functions of the state monad. ‹get› returns
the current state as result, does not fail, and does not change the state.
‹put s› returns nothing (@{typ unit}), changes the current state
to ‹s› and does not fail.
›
definition
get :: "('s,'s) det_monad" where
"get ≡ λs. ((s,s), False)"
definition
put :: "'s ⇒ ('s, unit) det_monad" where
"put s ≡ λ_. (((),s), False)"
subsection "Failure"
text ‹The monad function that always fails. Returns the current
state and sets the failure flag.›
definition
fail :: "'a ⇒ ('s, 'a) det_monad" where
"fail a ≡ λs. ((a,s), True)"
text ‹Assertions: fail if the property ‹P› is not true›
definition
assert :: "bool ⇒ ('a, unit) det_monad" where
"assert P ≡ if P then return () else fail ()"
text ‹An assertion that also can introspect the current state.›
definition
state_assert :: "('s ⇒ bool) ⇒ ('s, unit) det_monad"
where
"state_assert P ≡ get >>= (λs. assert (P s))"
subsection "Generic functions on top of the state monad"
text ‹Apply a function to the current state and return the result
without changing the state.›
definition
gets :: "('s ⇒ 'a) ⇒ ('s, 'a) det_monad" where
"gets f ≡ get >>= (λs. return (f s))"
text ‹Modify the current state using the function passed in.›
definition
modify :: "('s ⇒ 's) ⇒ ('s, unit) det_monad" where
"modify f ≡ get >>= (λs. put (f s))"
lemma simpler_gets_def: "gets f = (λs. ((f s, s), False))"
apply (simp add: gets_def return_def bind_def h1_def h2_def get_def)
done
lemma simpler_modify_def:
"modify f = (λs. (((), f s), False))"
by (simp add: modify_def bind_def h1_def h2_def get_def put_def)
text ‹Execute the given monad when the condition is true,
return ‹()› otherwise.›
definition
when1 :: "bool ⇒ ('s, unit) det_monad ⇒
('s, unit) det_monad" where
"when1 P m ≡ if P then m else return ()"
text ‹Execute the given monad unless the condition is true,
return ‹()› otherwise.›
definition
unless :: "bool ⇒ ('s, unit) det_monad ⇒
('s, unit) det_monad" where
"unless P m ≡ when1 (¬P) m"
text ‹
Perform a test on the current state, performing the left monad if
the result is true or the right monad if the result is false.
›
definition
condition :: "('s ⇒ bool) ⇒ ('s, 'r) det_monad ⇒ ('s, 'r) det_monad ⇒ ('s, 'r) det_monad"
where
"condition P L R ≡ λs. if (P s) then (L s) else (R s)"
notation (output)
condition ("(condition (_)// (_)// (_))" [1000,1000,1000] 1000)
subsection ‹The Monad Laws›
text ‹Each monad satisfies at least the following three laws.›
text ‹@{term return} is absorbed at the left of a @{term bind},
applying the return value directly:›
lemma return_bind [simp]: "(return x >>= f) = f x"
by (simp add: return_def bind_def h1_def h2_def)
text ‹@{term return} is absorbed on the right of a @{term bind}›
lemma bind_return [simp]: "(m >>= return) = m"
apply (rule ext)
apply (simp add: bind_def h1_def h2_def return_def split_def)
done
text ‹@{term bind} is associative›
lemma bind_assoc:
fixes m :: "('a,'b) det_monad"
fixes f :: "'b ⇒ ('a,'c) det_monad"
fixes g :: "'c ⇒ ('a,'d) det_monad"
shows "(m >>= f) >>= g = m >>= (λx. f x >>= g)"
apply (unfold bind_def h1_def h2_def Let_def split_def)
apply (rule ext)
apply clarsimp
done
section ‹Adding Exceptions›
text ‹
The type @{typ "('s,'a) det_monad"} gives us determinism and
failure. We now extend this monad with exceptional return values
that abort normal execution, but can be handled explicitly.
We use the sum type to indicate exceptions.
In @{typ "('s, 'e + 'a) det_monad"}, @{typ "'s"} is the state,
@{typ 'e} is an exception, and @{typ 'a} is a normal return value.
This new type itself forms a monad again. Since type classes in
Isabelle are not powerful enough to express the class of monads,
we provide new names for the @{term return} and @{term bind} functions
in this monad. We call them ‹returnOk› (for normal return values)
and ‹bindE› (for composition). We also define ‹throwError›
to return an exceptional value.
›
definition
returnOk :: "'a ⇒ ('s, 'e + 'a) det_monad" where
"returnOk ≡ return o Inr"
definition
throwError :: "'e ⇒ ('s, 'e + 'a) det_monad" where
"throwError ≡ return o Inl"
text ‹
Lifting a function over the exception type: if the input is an
exception, return that exception; otherwise continue execution.
›
definition
lift :: "('a ⇒ ('s, 'e + 'b) det_monad) ⇒
'e +'a ⇒ ('s, 'e + 'b) det_monad"
where
"lift f v ≡ case v of Inl e ⇒ throwError e
| Inr v' ⇒ f v'"
text ‹
The definition of @{term bind} in the exception monad (new
name ‹bindE›): the same as normal @{term bind}, but
the right-hand side is skipped if the left-hand side
produced an exception.
›
definition
bindE :: "('s, 'e + 'a) det_monad ⇒
('a ⇒ ('s, 'e + 'b) det_monad) ⇒
('s, 'e + 'b) det_monad" (infixl ">>=E" 60)
where
"bindE f g ≡ bind f (lift g)"
text ‹
Lifting a normal deterministic monad into the
exception monad is achieved by always returning its
result as normal result and never throwing an exception.
›
definition
liftE :: "('s,'a) det_monad ⇒ ('s, 'e+'a) det_monad"
where
"liftE f ≡ f >>= (λr. return (Inr r))"
text ‹
Since the underlying type and ‹return› function changed,
we need new definitions for when and unless:
›
definition
whenE :: "bool ⇒ ('s, 'e + unit) det_monad ⇒
('s, 'e + unit) det_monad"
where
"whenE P f ≡ if P then f else returnOk ()"
definition
unlessE :: "bool ⇒ ('s, 'e + unit) det_monad ⇒
('s, 'e + unit) det_monad"
where
"unlessE P f ≡ if P then returnOk () else f"
text ‹
Throwing an exception when the parameter is @{term None}, otherwise
returning @{term "v"} for @{term "Some v"}.
›
definition
throw_opt :: "'e ⇒ 'a option ⇒ ('s, 'e + 'a) det_monad" where
"throw_opt ex x ≡
case x of None ⇒ throwError ex | Some v ⇒ returnOk v"
subsection "Monad Laws for the Exception Monad"
text ‹More direct definition of @{const liftE}:›
lemma liftE_def2:
"liftE f = (λs. ((λ(v,s'). (Inr v, s')) (fst (f s)), snd (f s)))"
by (auto simp: Let_def liftE_def return_def split_def bind_def h1_def h2_def)
text ‹Left @{const returnOk} absorbtion over @{term bindE}:›
lemma returnOk_bindE [simp]: "(returnOk x >>=E f) = f x"
apply (unfold bindE_def returnOk_def)
apply (clarsimp simp: lift_def)
done
lemma lift_return [simp]:
"lift (return ∘ Inr) = return"
by (rule ext)
(simp add: lift_def throwError_def split: sum.splits)
text ‹Right @{const returnOk} absorbtion over @{term bindE}:›
lemma bindE_returnOk [simp]: "(m >>=E returnOk) = m"
by (simp add: bindE_def returnOk_def)
text ‹Associativity of @{const bindE}:›
lemma bindE_assoc:
"(m >>=E f) >>=E g = m >>=E (λx. f x >>=E g)"
apply (simp add: bindE_def bind_assoc)
apply (rule arg_cong [where f="λx. m >>= x"])
apply (rule ext)
apply (case_tac x, simp_all add: lift_def throwError_def)
done
text ‹@{const returnOk} could also be defined via @{const liftE}:›
lemma returnOk_liftE:
"returnOk x = liftE (return x)"
by (simp add: liftE_def returnOk_def)
text ‹Execution after throwing an exception is skipped:›
lemma throwError_bindE [simp]:
"(throwError E >>=E f) = throwError E"
by (simp add: bindE_def bind_def h1_def h2_def throwError_def lift_def return_def)
section "Syntax"
text ‹This section defines traditional Haskell-like do-syntax
for the state monad in Isabelle.›
subsection "Syntax for the Nondeterministic State Monad"
text ‹We use ‹K_bind› to syntactically indicate the
case where the return argument of the left side of a @{term bind}
is ignored›
definition
K_bind_def [iff]: "K_bind ≡ λx y. x"
nonterminal
dobinds and dobind and nobind
syntax
"_dobind" :: "[pttrn, 'a] => dobind" ("(_ ←/ _)" 10)
"" :: "dobind => dobinds" ("_")
"_nobind" :: "'a => dobind" ("_")
"_dobinds" :: "[dobind, dobinds] => dobinds" ("(_);//(_)")
"_do" :: "[dobinds, 'a] => 'a" ("(do ((_);//(_))//od)" 100)
translations
"_do (_dobinds b bs) e" == "_do b (_do bs e)"
"_do (_nobind b) e" == "b >>= (CONST K_bind e)"
"do x ← a; e od" == "a >>= (λx. e)"
text ‹Syntax examples:›
lemma "do x ← return 1;
return (2::nat);
return x
od =
return 1 >>=
(λx. return (2::nat) >>=
K_bind (return x))"
by (rule refl)
lemma "do x ← return 1;
return 2;
return x
od = return 1"
by simp
subsection "Syntax for the Exception Monad"
text ‹
Since the exception monad is a different type, we
need to syntactically distinguish it in the syntax.
We use ‹doE›/‹odE› for this, but can re-use
most of the productions from ‹do›/‹od›
above.
›
syntax
"_doE" :: "[dobinds, 'a] => 'a" ("(doE ((_);//(_))//odE)" 100)
translations
"_doE (_dobinds b bs) e" == "_doE b (_doE bs e)"
"_doE (_nobind b) e" == "b >>=E (CONST K_bind e)"
"doE x ← a; e odE" == "a >>=E (λx. e)"
text ‹Syntax examples:›
lemma "doE x ← returnOk 1;
returnOk (2::nat);
returnOk x
odE =
returnOk 1 >>=E
(λx. returnOk (2::nat) >>=E
K_bind (returnOk x))"
by (rule refl)
lemma "doE x ← returnOk 1;
returnOk 2;
returnOk x
odE = returnOk 1"
by simp
section "Library of Monadic Functions and Combinators"
text ‹Lifting a normal function into the monad type:›
definition
liftM :: "('a ⇒ 'b) ⇒ ('s,'a) det_monad ⇒ ('s, 'b) det_monad"
where
"liftM f m ≡ do x ← m; return (f x) od"
text ‹The same for the exception monad:›
definition
liftME :: "('a ⇒ 'b) ⇒ ('s,'e+'a) det_monad ⇒ ('s,'e+'b) det_monad"
where
"liftME f m ≡ doE x ← m; returnOk (f x) odE"
text ‹
Run a sequence of monads from left to right, ignoring return values.›
definition
sequence_x :: "('s, 'a) det_monad list ⇒ ('s, unit) det_monad"
where
"sequence_x xs ≡ foldr (λx y. x >>= (λ_. y)) xs (return ())"
text ‹
Map a monadic function over a list by applying it to each element
of the list from left to right, ignoring return values.
›
definition
mapM_x :: "('a ⇒ ('s,'b) det_monad) ⇒ 'a list ⇒ ('s, unit) det_monad"
where
"mapM_x f xs ≡ sequence_x (map f xs)"
text ‹
Map a monadic function with two parameters over two lists,
going through both lists simultaneously, left to right, ignoring
return values.
›
definition
zipWithM_x :: "('a ⇒ 'b ⇒ ('s,'c) det_monad) ⇒
'a list ⇒ 'b list ⇒ ('s, unit) det_monad"
where
"zipWithM_x f xs ys ≡ sequence_x (zipWith f xs ys)"
text ‹The same three functions as above, but returning a list of
return values instead of ‹unit››
definition
sequence :: "('s, 'a) det_monad list ⇒ ('s, 'a list) det_monad"
where
"sequence xs ≡ let mcons = (λp q. p >>= (λx. q >>= (λy. return (x#y))))
in foldr mcons xs (return [])"
definition
mapM :: "('a ⇒ ('s,'b) det_monad) ⇒ 'a list ⇒ ('s, 'b list) det_monad"
where
"mapM f xs ≡ sequence (map f xs)"
definition
zipWithM :: "('a ⇒ 'b ⇒ ('s,'c) det_monad) ⇒
'a list ⇒ 'b list ⇒ ('s, 'c list) det_monad"
where
"zipWithM f xs ys ≡ sequence (zipWith f xs ys)"
definition
foldM :: "('b ⇒ 'a ⇒ ('s, 'a) det_monad) ⇒ 'b list ⇒ 'a ⇒ ('s, 'a) det_monad"
where
"foldM m xs a ≡ foldr (λp q. q >>= m p) xs (return a) "
text ‹The sequence and map functions above for the exception monad,
with and without lists of return value›
definition
sequenceE_x :: "('s, 'e+'a) det_monad list ⇒ ('s, 'e+unit) det_monad"
where
"sequenceE_x xs ≡ foldr (λx y. doE _ ← x; y odE) xs (returnOk ())"
definition
mapME_x :: "('a ⇒ ('s,'e+'b) det_monad) ⇒ 'a list ⇒
('s,'e+unit) det_monad"
where
"mapME_x f xs ≡ sequenceE_x (map f xs)"
definition
sequenceE :: "('s, 'e+'a) det_monad list ⇒ ('s, 'e+'a list) det_monad"
where
"sequenceE xs ≡ let mcons = (λp q. p >>=E (λx. q >>=E (λy. returnOk (x#y))))
in foldr mcons xs (returnOk [])"
definition
mapME :: "('a ⇒ ('s,'e+'b) det_monad) ⇒ 'a list ⇒
('s,'e+'b list) det_monad"
where
"mapME f xs ≡ sequenceE (map f xs)"
text ‹Filtering a list using a monadic function as predicate:›
primrec
filterM :: "('a ⇒ ('s, bool) det_monad) ⇒ 'a list ⇒ ('s, 'a list) det_monad"
where
"filterM P [] = return []"
| "filterM P (x # xs) = do
b ← P x;
ys ← filterM P xs;
return (if b then (x # ys) else ys)
od"
section "Catching and Handling Exceptions"
text ‹
Turning an exception monad into a normal state monad
by catching and handling any potential exceptions:
›
definition
catch :: "('s, 'e + 'a) det_monad ⇒
('e ⇒ ('s, 'a) det_monad) ⇒
('s, 'a) det_monad" (infix "<catch>" 10)
where
"f <catch> handler ≡
do x ← f;
case x of
Inr b ⇒ return b
| Inl e ⇒ handler e
od"
text ‹
Handling exceptions, but staying in the exception monad.
The handler may throw a type of exceptions different from
the left side.
›
definition
handleE' :: "('s, 'e1 + 'a) det_monad ⇒
('e1 ⇒ ('s, 'e2 + 'a) det_monad) ⇒
('s, 'e2 + 'a) det_monad" (infix "<handle2>" 10)
where
"f <handle2> handler ≡
do
v ← f;
case v of
Inl e ⇒ handler e
| Inr v' ⇒ return (Inr v')
od"
text ‹
A type restriction of the above that is used more commonly in
practice: the exception handle (potentially) throws exception
of the same type as the left-hand side.
›
definition
handleE :: "('s, 'x + 'a) det_monad ⇒
('x ⇒ ('s, 'x + 'a) det_monad) ⇒
('s, 'x + 'a) det_monad" (infix "<handle>" 10)
where
"handleE ≡ handleE'"
text ‹
Handling exceptions, and additionally providing a continuation
if the left-hand side throws no exception:
›
definition
handle_elseE :: "('s, 'e + 'a) det_monad ⇒
('e ⇒ ('s, 'ee + 'b) det_monad) ⇒
('a ⇒ ('s, 'ee + 'b) det_monad) ⇒
('s, 'ee + 'b) det_monad"
("_ <handle> _ <else> _" 10)
where
"f <handle> handler <else> continue ≡
do v ← f;
case v of Inl e ⇒ handler e
| Inr v' ⇒ continue v'
od"
section "Hoare Logic"
subsection "Validity"
text ‹This section defines a Hoare logic for partial correctness for
the deterministic state monad as well as the exception monad.
The logic talks only about the behaviour part of the monad and ignores
the failure flag.
The logic is defined semantically. Rules work directly on the
validity predicate.
In the deterministic state monad, validity is a triple of precondition,
monad, and postcondition. The precondition is a function from state to
bool (a state predicate), the postcondition is a function from return value
to state to bool. A triple is valid if for all states that satisfy the
precondition, all result values and result states that are returned by
the monad satisfy the postcondition. Note that if the computation returns
the empty set, the triple is trivially valid. This means @{term "assert P"}
does not require us to prove that @{term P} holds, but rather allows us
to assume @{term P}! Proving non-failure is done via separate predicate and
calculus (see below).
›
definition
valid :: "('s ⇒ bool) ⇒ ('s,'a) det_monad ⇒ ('a ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /⦃_⦄")
where
"⦃P⦄ f ⦃Q⦄ ≡ ∀s. P s ⟶ (∀r s'. ((r,s') = fst (f s) ⟶ Q r s'))"
text ‹
Validity for the exception monad is similar and build on the standard
validity above. Instead of one postcondition, we have two: one for
normal and one for exceptional results.
›
definition
validE :: "('s ⇒ bool) ⇒ ('s, 'a + 'b) det_monad ⇒
('b ⇒ 's ⇒ bool) ⇒
('a ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /(⦃_⦄,/ ⦃_⦄)")
where
"⦃P⦄ f ⦃Q⦄,⦃E⦄ ≡ ⦃P⦄ f ⦃ λv s. case v of Inr r ⇒ Q r s | Inl e ⇒ E e s ⦄"
text ‹
The following two instantiations are convenient to separate reasoning
for exceptional and normal case.
›
definition
validE_R :: "('s ⇒ bool) ⇒ ('s, 'e + 'a) det_monad ⇒
('a ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /⦃_⦄, -")
where
"⦃P⦄ f ⦃Q⦄,- ≡ validE P f Q (λx y. True)"
definition
validE_E :: "('s ⇒ bool) ⇒ ('s, 'e + 'a) det_monad ⇒
('e ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /-, ⦃_⦄")
where
"⦃P⦄ f -,⦃Q⦄ ≡ validE P f (λx y. True) Q"
text ‹Abbreviations for trivial preconditions:›
abbreviation(input)
top :: "'a ⇒ bool" ("⊤")
where
"⊤ ≡ λ_. True"
abbreviation(input)
bottom :: "'a ⇒ bool" ("⊥")
where
"⊥ ≡ λ_. False"
text ‹Abbreviations for trivial postconditions (taking two arguments):›
abbreviation(input)
toptop :: "'a ⇒ 'b ⇒ bool" ("⊤⊤")
where
"⊤⊤ ≡ λ_ _. True"
abbreviation(input)
botbot :: "'a ⇒ 'b ⇒ bool" ("⊥⊥")
where
"⊥⊥ ≡ λ_ _. False"
text ‹
Lifting ‹∧› and ‹∨› over two arguments.
Lifting ‹∧› and ‹∨› over one argument is already
defined (written ‹and› and ‹or›).
›
definition
bipred_conj :: "('a ⇒ 'b ⇒ bool) ⇒ ('a ⇒ 'b ⇒ bool) ⇒ ('a ⇒ 'b ⇒ bool)"
(infixl "And" 96)
where
"bipred_conj P Q ≡ λx y. P x y ∧ Q x y"
definition
bipred_disj :: "('a ⇒ 'b ⇒ bool) ⇒ ('a ⇒ 'b ⇒ bool) ⇒ ('a ⇒ 'b ⇒ bool)"
(infixl "Or" 91)
where
"bipred_disj P Q ≡ λx y. P x y ∨ Q x y"
subsection "Determinism"
text ‹A monad of type ‹det_monad› is deterministic iff it
returns exactly one state and result and does not fail›
definition
det :: "('a,'s) det_monad ⇒ bool"
where
"det f ≡ ∀s. ∃r. f s = (r,False)"
text ‹A deterministic ‹det_monad› can be turned
into a normal state monad:›
definition
the_run_state :: "('s,'a) det_monad ⇒ 's ⇒ 'a × 's"
where
"the_run_state M ≡ λs. THE s'. fst (M s) = s'"
subsection "Non-Failure"
text ‹
With the failure flag, we can formulate non-failure separately
from validity. A monad ‹m› does not fail under precondition
‹P›, if for no start state in that precondition it sets
the failure flag.
›
definition
no_fail :: "('s ⇒ bool) ⇒ ('s,'a) det_monad ⇒ bool"
where
"no_fail P m ≡ ∀s. P s ⟶ ¬ (snd (m s))"
text ‹
It is often desired to prove non-failure and a Hoare triple
simultaneously, as the reasoning is often similar. The following
definitions allow such reasoning to take place.
›
definition
validNF ::"('s ⇒ bool) ⇒ ('s,'a) det_monad ⇒ ('a ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /⦃_⦄!")
where
"validNF P f Q ≡ valid P f Q ∧ no_fail P f"
definition
validE_NF :: "('s ⇒ bool) ⇒ ('s, 'a + 'b) det_monad ⇒
('b ⇒ 's ⇒ bool) ⇒
('a ⇒ 's ⇒ bool) ⇒ bool"
("⦃_⦄/ _ /(⦃_⦄,/ ⦃_⦄!)")
where
"validE_NF P f Q E ≡ validE P f Q E ∧ no_fail P f"
lemma validE_NF_alt_def:
"⦃ P ⦄ B ⦃ Q ⦄,⦃ E ⦄! = ⦃ P ⦄ B ⦃ λv s. case v of Inl e ⇒ E e s | Inr r ⇒ Q r s ⦄!"
by (clarsimp simp: validE_NF_def validE_def validNF_def)
section "Basic exception reasoning"
text ‹
The following predicates ‹no_throw› and ‹no_return› allow
reasoning that functions in the exception monad either do
no throw an exception or never return normally.
›
definition "no_throw P A ≡ ⦃ P ⦄ A ⦃ λ_ _. True ⦄,⦃ λ_ _. False ⦄"
definition "no_return P A ≡ ⦃ P ⦄ A ⦃λ_ _. False⦄,⦃λ_ _. True ⦄"
end
Theory DetMonadLemmas
theory DetMonadLemmas
imports DetMonad
begin
section "General Lemmas Regarding the Deterministic State Monad"
subsection "Congruence Rules for the Function Package"
lemma bind_cong[fundef_cong]:
"⟦ f = f'; ⋀v s s'. (v, s') = fst (f' s) ⟹ g v s' = g' v s' ⟧ ⟹ f >>= g = f' >>= g'"
apply (rule ext)
apply (auto simp: bind_def h1_def h2_def Let_def split_def intro: rev_image_eqI)
done
lemma bind_apply_cong [fundef_cong]:
"⟦ f s = f' s'; ⋀rv st. (rv, st) = fst (f' s') ⟹ g rv st = g' rv st ⟧
⟹ (f >>= g) s = (f' >>= g') s'"
apply (simp add: bind_def h1_def h2_def)
apply (auto simp: split_def intro: SUP_cong [OF refl] intro: rev_image_eqI)
done
lemma bindE_cong[fundef_cong]:
"⟦ M = M' ; ⋀v s s'. (Inr v, s') = fst (M' s) ⟹ N v s' = N' v s' ⟧ ⟹ bindE M N = bindE M' N'"
apply (simp add: bindE_def)
apply (rule bind_cong)
apply (rule refl)
apply (unfold lift_def)
apply (case_tac v, simp_all)
done
lemma bindE_apply_cong[fundef_cong]:
"⟦ f s = f' s'; ⋀rv st. (Inr rv, st) = fst (f' s') ⟹ g rv st = g' rv st ⟧
⟹ (f >>=E g) s = (f' >>=E g') s'"
apply (simp add: bindE_def)
apply (rule bind_apply_cong)
apply assumption
apply (case_tac rv, simp_all add: lift_def)
done
lemma K_bind_apply_cong[fundef_cong]:
"⟦ f st = f' st' ⟧ ⟹ K_bind f arg st = K_bind f' arg' st'"
by simp
lemma when_apply_cong[fundef_cong]:
"⟦ C = C'; s = s'; C' ⟹ m s' = m' s' ⟧ ⟹ whenE C m s = whenE C' m' s'"
by (simp add: whenE_def)
lemma unless_apply_cong[fundef_cong]:
"⟦ C = C'; s = s'; ¬ C' ⟹ m s' = m' s' ⟧ ⟹ unlessE C m s = unlessE C' m' s'"
by (simp add: unlessE_def)
lemma whenE_apply_cong[fundef_cong]:
"⟦ C = C'; s = s'; C' ⟹ m s' = m' s' ⟧ ⟹ whenE C m s = whenE C' m' s'"
by (simp add: whenE_def)
lemma unlessE_apply_cong[fundef_cong]:
"⟦ C = C'; s = s'; ¬ C' ⟹ m s' = m' s' ⟧ ⟹ unlessE C m s = unlessE C' m' s'"
by (simp add: unlessE_def)
subsection "Simplifying Monads"
lemma nested_bind [simp]:
"do x ← do y ← f; return (g y) od; h x od =
do y ← f; h (g y) od"
apply (clarsimp simp add: bind_def h1_def h2_def)
apply (rule ext)
apply (clarsimp simp add: Let_def split_def return_def)
done
lemma assert_True [simp]:
"assert True >>= f = f ()"
by (simp add: assert_def)
lemma when_True_bind [simp]:
"when1 True g >>= f = g >>= f"
by (simp add: when1_def bind_def return_def)
lemma whenE_False_bind [simp]:
"whenE False g >>=E f = f ()"
by (simp add: whenE_def bindE_def returnOk_def lift_def)
lemma whenE_True_bind [simp]:
"whenE True g >>=E f = g >>=E f"
by (simp add: whenE_def bindE_def returnOk_def lift_def)
lemma when_True [simp]: "when1 True X = X"
by (clarsimp simp: when1_def)
lemma when_False [simp]: "when1 False X = return ()"
by (clarsimp simp: when1_def)
lemma unless_False [simp]: "unless False X = X"
by (clarsimp simp: unless_def)
lemma unless_True [simp]: "unless True X = return ()"
by (clarsimp simp: unless_def)
lemma unlessE_whenE:
"unlessE P = whenE (~P)"
by (rule ext)+ (simp add: unlessE_def whenE_def)
lemma unless_when:
"unless P = when1 (~P)"
by (rule ext)+ (simp add: unless_def when1_def)
lemma gets_to_return [simp]: "gets (λs. v) = return v"
by (clarsimp simp: gets_def put_def get_def bind_def h1_def h2_def return_def)
lemma liftE_handleE' [simp]: "((liftE a) <handle2> b) = liftE a"
apply (clarsimp simp: liftE_def handleE'_def)
done
lemma liftE_handleE [simp]: "((liftE a) <handle> b) = liftE a"
apply (unfold handleE_def)
apply simp
done
lemma condition_split:
"P (condition C a b s) = ((((C s) ⟶ P (a s)) ∧ (¬ (C s) ⟶ P (b s))))"
apply (clarsimp simp: condition_def)
done
lemma condition_split_asm:
"P (condition C a b s) = (¬ (C s ∧ ¬ P (a s) ∨ ¬ C s ∧ ¬ P (b s)))"
apply (clarsimp simp: condition_def)
done
lemmas condition_splits = condition_split condition_split_asm
lemma condition_true_triv [simp]:
"condition (λ_. True) A B = A"
apply (rule ext)
apply (clarsimp split: condition_splits)
done
lemma condition_false_triv [simp]:
"condition (λ_. False) A B = B"
apply (rule ext)
apply (clarsimp split: condition_splits)
done
lemma condition_true: "⟦ P s ⟧ ⟹ condition P A B s = A s"
apply (clarsimp simp: condition_def)
done
lemma condition_false: "⟦ ¬ P s ⟧ ⟹ condition P A B s = B s"
apply (clarsimp simp: condition_def)
done
section "Low-level monadic reasoning"
lemma valid_make_schematic_post:
"(∀s0. ⦃ λs. P s0 s ⦄ f ⦃ λrv s. Q s0 rv s ⦄) ⟹
⦃ λs. ∃s0. P s0 s ∧ (∀rv s'. Q s0 rv s' ⟶ Q' rv s') ⦄ f ⦃ Q' ⦄"
by (auto simp add: valid_def no_fail_def split: prod.splits)
lemma validNF_make_schematic_post:
"(∀s0. ⦃ λs. P s0 s ⦄ f ⦃ λrv s. Q s0 rv s ⦄!) ⟹
⦃ λs. ∃s0. P s0 s ∧ (∀rv s'. Q s0 rv s' ⟶ Q' rv s') ⦄ f ⦃ Q' ⦄!"
by (auto simp add: valid_def validNF_def no_fail_def split: prod.splits)
lemma validE_make_schematic_post:
"(∀s0. ⦃ λs. P s0 s ⦄ f ⦃ λrv s. Q s0 rv s ⦄, ⦃ λrv s. E s0 rv s ⦄) ⟹
⦃ λs. ∃s0. P s0 s ∧ (∀rv s'. Q s0 rv s' ⟶ Q' rv s')
∧ (∀rv s'. E s0 rv s' ⟶ E' rv s') ⦄ f ⦃ Q' ⦄, ⦃ E' ⦄"
by (auto simp add: validE_def valid_def no_fail_def split: prod.splits sum.splits)
lemma validE_NF_make_schematic_post:
"(∀s0. ⦃ λs. P s0 s ⦄ f ⦃ λrv s. Q s0 rv s ⦄, ⦃ λrv s. E s0 rv s ⦄!) ⟹
⦃ λs. ∃s0. P s0 s ∧ (∀rv s'. Q s0 rv s' ⟶ Q' rv s')
∧ (∀rv s'. E s0 rv s' ⟶ E' rv s') ⦄ f ⦃ Q' ⦄, ⦃ E' ⦄!"
by (auto simp add: validE_NF_def validE_def valid_def no_fail_def split: prod.splits sum.splits)
lemma validNF_conjD1: "⦃ P ⦄ f ⦃ λrv s. Q rv s ∧ Q' rv s ⦄! ⟹ ⦃ P ⦄ f ⦃ Q ⦄!"
by (fastforce simp: validNF_def valid_def no_fail_def)
lemma validNF_conjD2: "⦃ P ⦄ f ⦃ λrv s. Q rv s ∧ Q' rv s ⦄! ⟹ ⦃ P ⦄ f ⦃ Q' ⦄!"
by (fastforce simp: validNF_def valid_def no_fail_def)
lemma exec_gets:
"(gets f >>= m) s = m (f s) s"
by (simp add: simpler_gets_def bind_def h1_def h2_def)
lemma in_gets:
"(r, s') = fst (gets f s) = (r = f s ∧ s' = s)"
by (simp add: simpler_gets_def)
end
Theory RegistersOps
section‹Register Operations›
theory RegistersOps
imports Main "../lib/WordDecl" "Word_Lib.Traditional_Infix_Syntax"
begin
text‹
This theory provides operations to get, set and clear bits in registers
›
section "Getting Fields"
text‹
Get a field of type @{typ "'b::len word"}
starting at @{term "index"} from @{term "addr"} of type @{typ "'a::len word"}
›
definition get_field_from_word_a_b:: "'a::len word ⇒ nat ⇒ 'b::len word"
where
"get_field_from_word_a_b addr index
≡ let off = (size addr - LENGTH('b))
in ucast ((addr << (off-index)) >> off)"
text‹
Obtain, from addr of type @{typ "'a::len word"},
another @{typ "'a::len word"} containing the field of length ‹len›
starting at ‹index› in ‹addr›.
›
definition get_field_from_word_a_a:: "'a::len word ⇒ nat ⇒ nat ⇒ 'a::len word"
where
"get_field_from_word_a_a addr index len
≡ (addr << (size addr - (index+len)) >> (size addr - len))"
section "Setting Fields"
text‹
Set the field of type @{typ "'b::len word"}
at ‹index› from ‹record›
of type @{typ "'a::len word"}.
›
definition set_field :: "'a::len word ⇒ 'b::len word ⇒ nat ⇒ 'a::len word"
where
"set_field record field index
≡ let mask:: ('a::len word) = (mask (size field)) << index
in (record AND (NOT mask)) OR ((ucast field) << index)"
section "Clearing Fields"
text‹
Zero the ‹n› initial bits of ‹addr›.
›
definition clear_n_bits:: "'a::len word ⇒ nat ⇒ 'a::len word"
where
"clear_n_bits addr n ≡ addr AND (NOT (mask n))"
text‹
Gets the natural value of a 32 bit mask
›
definition get_nat_from_mask::"word32 ⇒ nat ⇒ nat ⇒ (word32 × nat)"
where
"
get_nat_from_mask w m v ≡ if (w AND (mask m) =0) then (w>>m, v+m)
else (w,m)
"
definition get_nat_from_mask32::"word32⇒ nat"
where
"get_nat_from_mask32 w ≡
if (w=0) then len_of TYPE (word_length32)
else
let (w,res) = get_nat_from_mask w 16 0 in
let (w,res)= get_nat_from_mask w 8 res in
let (w,res) = get_nat_from_mask w 4 res in
let (w,res) = get_nat_from_mask w 2 res in
let (w,res) = get_nat_from_mask w 1 res in
res
"
end
Theory MMU
section ‹Memory Management Unit (MMU)›
theory MMU
imports Main RegistersOps Sparc_Types
begin
section ‹MMU Sizing›
text‹
We need some citation here for documentation about the MMU.
›
text‹The MMU uses the Address Space Identifiers (ASI) to control memory access.
ASI = 8, 10 are for user; ASI = 9, 11 are for supervisor.›
subsection "MMU Types"
type_synonym word_PTE_flags = word8
type_synonym word_length_PTE_flags = word_length8
subsection "MMU length values"
text‹Definitions for the length of the virtua address, page size,
virtual translation tables indexes, virtual address offset and Page protection flags›
definition length_entry_type :: "nat"
where "length_entry_type ≡ LENGTH(word_length_entry_type)"
definition length_phys_address:: "nat"
where "length_phys_address ≡ LENGTH(word_length_phys_address)"
definition length_virtua_address:: "nat"
where "length_virtua_address ≡ LENGTH(word_length_virtua_address)"
definition length_page:: "nat" where "length_page ≡ LENGTH(word_length_page)"
definition length_t1:: "nat" where "length_t1 ≡ LENGTH(word_length_t1)"
definition length_t2:: "nat" where "length_t2 ≡ LENGTH(word_length_t2)"
definition length_t3:: "nat" where "length_t3 ≡ LENGTH(word_length_t3)"
definition length_offset:: "nat" where "length_offset ≡ LENGTH(word_length_offset)"
definition length_PTE_flags :: "nat" where
"length_PTE_flags ≡ LENGTH(word_length_PTE_flags)"
subsection "MMU index values"
definition va_t1_index :: "nat" where "va_t1_index ≡ length_virtua_address - length_t1"
definition va_t2_index :: "nat" where "va_t2_index ≡ va_t1_index - length_t2"
definition va_t3_index :: "nat" where "va_t3_index ≡ va_t2_index - length_t3"
definition va_offset_index :: "nat" where "va_offset_index ≡ va_t3_index - length_offset"
definition pa_page_index :: "nat"
where "pa_page_index ≡ length_phys_address - length_page"
definition pa_offset_index :: "nat" where
"pa_offset_index ≡ pa_page_index -length_page"
section ‹MMU Definition›
record MMU_state =
registers :: "MMU_context"
text ‹The following functions access MMU registers via addresses.
See UT699LEON3FT manual page 35.›
definition mmu_reg_val:: "MMU_state ⇒ virtua_address ⇒ machine_word option"
where "mmu_reg_val mmu_state addr ≡
if addr = 0x000 then
Some ((registers mmu_state) CR)
else if addr = 0x100 then
Some ((registers mmu_state) CTP)
else if addr = 0x200 then
Some ((registers mmu_state) CNR)
else if addr = 0x300 then
Some ((registers mmu_state) FTSR)
else if addr = 0x400 then
Some ((registers mmu_state) FAR)
else None"
definition mmu_reg_mod:: "MMU_state ⇒ virtua_address ⇒ machine_word ⇒
MMU_state option" where
"mmu_reg_mod mmu_state addr w ≡
if addr = 0x000 then
Some (mmu_state⦇registers := (registers mmu_state)(CR := w)⦈)
else if addr = 0x100 then
Some (mmu_state⦇registers := (registers mmu_state)(CTP := w)⦈)
else if addr = 0x200 then
Some (mmu_state⦇registers := (registers mmu_state)(CNR := w)⦈)
else if addr = 0x300 then
Some (mmu_state⦇registers := (registers mmu_state)(FTSR := w)⦈)
else if addr = 0x400 then
Some (mmu_state⦇registers := (registers mmu_state)(FAR := w)⦈)
else None"
section ‹Virtual Memory›
subsection ‹MMU Auxiliary Definitions›
definition getCTPVal:: "MMU_state ⇒ machine_word"
where "getCTPVal mmu ≡ (registers mmu) CTP"
definition getCNRVal::"MMU_state ⇒ machine_word"
where "getCNRVal mmu ≡ (registers mmu) CNR"
text‹
The physical context table address is got from the ConText Pointer register (CTP) and the
Context Register (CNR) MMU registers.
The CTP is shifted to align it with
the physical address (36 bits) and we add the table index given on CNR.
CTP is right shifted 2 bits, cast to phys address and left shifted 6 bytes
to be aligned with the context register.
CNR is 2 bits left shifted for alignment with the context table.
›
definition compose_context_table_addr :: "machine_word ⇒machine_word
⇒ phys_address"
where
"compose_context_table_addr ctp cnr
≡ ((ucast (ctp >> 2)) << 6) + (ucast cnr << 2)"
subsection ‹Virtual Address Translation›
text‹Get the context table phys address from the MMU registers›
definition get_context_table_addr :: "MMU_state ⇒ phys_address"
where
"get_context_table_addr mmu
≡ compose_context_table_addr (getCTPVal mmu) (getCNRVal mmu)"
definition va_list_index :: "nat list" where
"va_list_index ≡ [va_t1_index,va_t2_index,va_t3_index,0]"
definition offset_index :: "nat list" where
"offset_index
≡ [ length_machine_word
, length_machine_word-length_t1
, length_machine_word-length_t1-length_t2
, length_machine_word-length_t1-length_t2-length_t3
]"
definition index_len_table :: "nat list" where "index_len_table ≡ [8,6,6,0]"
definition n_context_tables :: "nat" where "n_context_tables ≡ 3"
text ‹The following are basic physical memory read functions.
At this level we don't need the write memory yet.›
definition mem_context_val:: "asi_type ⇒ phys_address ⇒
mem_context ⇒ mem_val_type option"
where
"mem_context_val asi add m ≡
let asi8 = word_of_int 8;
r1 = m asi add
in
if r1 = None then
m asi8 add
else r1
"
text ‹Given an ASI (word8), an address (word32) addr,
read the 32bit value from the memory addresses
starting from address addr' where addr' = addr
exception that the last two bits are 0's.
That is, read the data from
addr', addr'+1, addr'+2, addr'+3.›
definition mem_context_val_w32 :: "asi_type ⇒ phys_address ⇒
mem_context ⇒ word32 option"
where
"mem_context_val_w32 asi addr m ≡
let addr' = (AND) addr 0b111111111111111111111111111111111100;
addr0 = (OR) addr' 0b000000000000000000000000000000000000;
addr1 = (OR) addr' 0b000000000000000000000000000000000001;
addr2 = (OR) addr' 0b000000000000000000000000000000000010;
addr3 = (OR) addr' 0b000000000000000000000000000000000011;
r0 = mem_context_val asi addr0 m;
r1 = mem_context_val asi addr1 m;
r2 = mem_context_val asi addr2 m;
r3 = mem_context_val asi addr3 m
in
if r0 = None ∨ r1 = None ∨ r2 = None ∨ r3 = None then
None
else
let byte0 = case r0 of Some v ⇒ v;
byte1 = case r1 of Some v ⇒ v;
byte2 = case r2 of Some v ⇒ v;
byte3 = case r3 of Some v ⇒ v
in
Some ((OR) ((OR) ((OR) ((ucast(byte0)) << 24)
((ucast(byte1)) << 16))
((ucast(byte2)) << 8))
(ucast(byte3)))
"
text ‹
@{term "get_addr_from_table"} browses the page description tables
until it finds a PTE (bits==suc (suc 0).
If it is a PTE it aligns the 24 most significant bits of the entry
with the most significant bits of the phys address and or-ed with the offset,
which will vary depending on the entry level.
In the case we are looking at the last table level (level 3),
the offset is aligned to 0 otherwise it will be 2.
If the table entry is a PTD (bits== Suc 0),
the index is obtained from the virtual address depending on the current level and or-ed with the PTD.
›
function ptd_lookup:: "virtua_address ⇒ virtua_address ⇒
mem_context ⇒ nat ⇒ (phys_address × PTE_flags) option"
where "ptd_lookup va pt m lvl = (
if lvl > 3 then None
else
let thislvl_offset = (
if lvl = 1 then (ucast ((ucast (va >> 24))::word8))::word32
else if lvl = 2 then (ucast ((ucast (va >> 18))::word6))::word32
else (ucast ((ucast (va >> 12))::word6))::word32);
thislvl_addr = (OR) pt thislvl_offset;
thislvl_data = mem_context_val_w32 (word_of_int 9) (ucast thislvl_addr) m
in
case thislvl_data of
Some v ⇒ (
let et_val = (AND) v 0b00000000000000000000000000000011 in
if et_val = 0 then
None
else if et_val = 1 then
let ptp = (AND) v 0b11111111111111111111111111111100 in
ptd_lookup va ptp m (lvl+1)
else if et_val = 2 then
let ppn = (ucast (v >> 8))::word24;
va_offset = (ucast ((ucast va)::word12))::word36
in
Some (((OR) (((ucast ppn)::word36) << 12) va_offset),
((ucast v)::word8))
else
None
)
|None ⇒ None)
"
by pat_completeness auto
termination
by (relation "measure (λ (va, (pt, (m, lvl))). 4 - lvl)") auto
definition get_acc_flag:: "PTE_flags ⇒ word3" where
"get_acc_flag w8 ≡ (ucast (w8 >> 2))::word3"
definition mmu_readable:: "word3 ⇒ asi_type ⇒ bool" where
"mmu_readable f asi ≡
if uint asi ∈ {8, 10} then
if uint f ∈ {0,1,2,3,5} then True
else False
else if uint asi ∈ {9, 11} then
if uint f ∈ {0,1,2,3,5,6,7} then True
else False
else False
"
definition mmu_writable:: "word3 ⇒ asi_type ⇒ bool" where
"mmu_writable f asi ≡
if uint asi ∈ {8, 10} then
if uint f ∈ {1,3} then True
else False
else if uint asi ∈ {9, 11} then
if uint f ∈ {1,3,5,7} then True
else False
else False
"
definition virt_to_phys :: "virtua_address ⇒ MMU_state ⇒ mem_context ⇒
(phys_address × PTE_flags) option"
where
"virt_to_phys va mmu m ≡
let ctp_val = mmu_reg_val mmu (0x100);
cnr_val = mmu_reg_val mmu (0x200);
mmu_cr_val = (registers mmu) CR
in
if (AND) mmu_cr_val 1 ≠ 0 then
case (ctp_val,cnr_val) of
(Some v1, Some v2) ⇒
let context_table_entry = (OR) ((v1 >> 11) << 11)
(((AND) v2 0b00000000000000000000000111111111) << 2);
context_table_data = mem_context_val_w32 (word_of_int 9)
(ucast context_table_entry) m
in (
case context_table_data of
Some lvl1_page_table ⇒
ptd_lookup va lvl1_page_table m 1
|None ⇒ None)
|_ ⇒ None
else Some ((ucast va), ((0b11101111)::word8))
"
text ‹
\newpage
The below function gives the initial values of MMU registers.
In particular, the MMU context register CR is 0 because:
We don't know the bits for IMPL, VER, and SC;
the bits for PSO are 0s because we use TSO;
the reserved bits are 0s;
we assume NF bits are 0s;
and most importantly, the E bit is 0 because when the machine
starts up, MMU is disabled.
An initial boot procedure (bootloader or something like that) should
configure the MMU and then enable it if the OS uses MMU.›
definition MMU_registers_init :: "MMU_context"
where "MMU_registers_init r ≡ 0"
definition mmu_setup :: "MMU_state"
where "mmu_setup ≡ ⦇registers=MMU_registers_init⦈"
end
Theory Sparc_State
section ‹SPARC V8 state model›
theory Sparc_State
imports Main Sparc_Types "../lib/wp/DetMonadLemmas" MMU
begin
section ‹state as a function›
record cpu_cache =
dcache:: cache_context
icache:: cache_context
text‹
The state @{term sparc_state} is defined as a tuple @{term cpu_context},
@{term user_context}, @{term mem_context}, defining the state of the CPU registers,
user registers, memory, cache, and delayed write pool respectively.
Additionally, a boolean indicates whether the state is
undefined or not.
›
record (overloaded) ('a) sparc_state =
cpu_reg:: cpu_context
user_reg:: "('a) user_context"
sys_reg:: sys_context
mem:: mem_context
mmu:: MMU_state
cache:: cpu_cache
dwrite:: delayed_write_pool
state_var:: sparc_state_var
traps:: "Trap set"
undef:: bool
section‹functions for state member access›
definition cpu_reg_val:: "CPU_register ⇒ ('a) sparc_state ⇒ reg_type"
where
"cpu_reg_val reg state ≡ (cpu_reg state) reg"
definition cpu_reg_mod :: "word32 ⇒ CPU_register ⇒ ('a) sparc_state ⇒
('a) sparc_state"
where "cpu_reg_mod data_w32 cpu state ≡
state⦇cpu_reg := ((cpu_reg state)(cpu := data_w32))⦈"
text ‹r[0] = 0. Otherwise read the actual value.›
definition user_reg_val:: "('a) window_size ⇒ user_reg_type ⇒ ('a) sparc_state ⇒ reg_type"
where
"user_reg_val window ur state ≡
if ur = 0 then 0
else (user_reg state) window ur"
text ‹Write a global register. win should be initialised as NWINDOWS.›
fun (sequential) global_reg_mod :: "word32 ⇒ nat ⇒ user_reg_type ⇒
('a::len) sparc_state ⇒ ('a) sparc_state"
where
"global_reg_mod data_w32 0 ur state = state"
|
"global_reg_mod data_w32 win ur state = (
let win_word = word_of_int (int (win-1));
ns = state⦇user_reg :=
(user_reg state)(win_word := ((user_reg state) win_word)(ur := data_w32))⦈
in
global_reg_mod data_w32 (win-1) ur ns
)"
text ‹Compute the next window.›
definition next_window :: "('a::len) window_size ⇒ ('a) window_size"
where
"next_window win ≡
if (uint win) < (NWINDOWS - 1) then (win + 1)
else 0
"
text ‹Compute the previous window.›
definition pre_window :: "('a::len) window_size ⇒ ('a::len) window_size"
where
"pre_window win ≡
if (uint win) > 0 then (win - 1)
else (word_of_int (NWINDOWS - 1))
"
text ‹write an output register.
Also write ur+16 of the previous window.›
definition out_reg_mod :: "word32 ⇒ ('a::len) window_size ⇒ user_reg_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"out_reg_mod data_w32 win ur state ≡
let state' = state⦇user_reg :=
(user_reg state)(win := ((user_reg state) win)(ur := data_w32))⦈;
win' = pre_window win;
ur' = ur + 16
in
state'⦇user_reg :=
(user_reg state')(win' := ((user_reg state') win')(ur' := data_w32))⦈
"
text ‹Write a input register.
Also write ur-16 of the next window.›
definition in_reg_mod :: "word32 ⇒ ('a::len) window_size ⇒ user_reg_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"in_reg_mod data_w32 win ur state ≡
let state' = state⦇user_reg :=
(user_reg state)(win := ((user_reg state) win)(ur := data_w32))⦈;
win' = next_window win;
ur' = ur - 16
in
state'⦇user_reg :=
(user_reg state')(win' := ((user_reg state') win')(ur' := data_w32))⦈
"
text ‹Do not modify r[0].›
definition user_reg_mod :: "word32 ⇒ ('a::len) window_size ⇒ user_reg_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"user_reg_mod data_w32 win ur state ≡
if ur = 0 then state
else if 0 < ur ∧ ur < 8 then
global_reg_mod data_w32 (nat NWINDOWS) ur state
else if 7 < ur ∧ ur < 16 then
out_reg_mod data_w32 win ur state
else if 15 < ur ∧ ur < 24 then
state⦇user_reg :=
(user_reg state)(win := ((user_reg state) win)(ur := data_w32))⦈
else
in_reg_mod data_w32 win ur state
"
definition sys_reg_val :: "sys_reg ⇒ ('a) sparc_state ⇒ reg_type"
where
"sys_reg_val reg state ≡ (sys_reg state) reg"
definition sys_reg_mod :: "word32 ⇒ sys_reg ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"sys_reg_mod data_w32 sys state ≡ state⦇sys_reg := (sys_reg state)(sys := data_w32)⦈"
text ‹The following fucntions deal with physical memory.
N.B. Physical memory address in SPARCv8 is 36-bit.›
text ‹LEON3 doesn't distinguish ASI 8 and 9; 10 and 11 for read access
for both user and supervisor.
We recently discovered that the compiled machine code by
the sparc-elf compiler often reads asi = 10 (user data)
when the actual content is store in asi = 8 (user instruction).
For testing purposes, we don't distinguish asi = 8,9,10,11
for reading access.›
definition mem_val:: "asi_type ⇒ phys_address ⇒
('a) sparc_state ⇒ mem_val_type option"
where
"mem_val asi add state ≡
let asi8 = word_of_int 8;
asi9 = word_of_int 9;
asi10 = word_of_int 10;
asi11 = word_of_int 11;
r1 = (mem state) asi8 add
in
if r1 = None then
let r2 = (mem state) asi9 add in
if r2 = None then
let r3 = (mem state) asi10 add in
if r3 = None then
(mem state) asi11 add
else r3
else r2
else r1
"
text ‹An alternative way to read values from memory.
Some implementations may use this definition.›
definition mem_val_alt:: "asi_type ⇒ phys_address ⇒
('a) sparc_state ⇒ mem_val_type option"
where
"mem_val_alt asi add state ≡
let r1 = (mem state) asi add;
asi8 = word_of_int 8;
asi9 = word_of_int 9;
asi10 = word_of_int 10;
asi11 = word_of_int 11
in
if r1 = None ∧ (uint asi) = 8 then
let r2 = (mem state) asi9 add in
r2
else if r1 = None ∧ (uint asi) = 9 then
let r2 = (mem state) asi8 add in
r2
else if r1 = None ∧ (uint asi) = 10 then
let r2 = (mem state) asi11 add in
if r2 = None then
let r3 = (mem state) asi8 add in
if r3 = None then
(mem state) asi9 add
else r3
else r2
else if r1 = None ∧ (uint asi) = 11 then
let r2 = (mem state) asi10 add in
if r2 = None then
let r3 = (mem state) asi8 add in
if r3 = None then
(mem state) asi9 add
else r3
else r2
else r1"
definition mem_mod :: "asi_type ⇒ phys_address ⇒ mem_val_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"mem_mod asi addr val state ≡
let state1 = state⦇mem := (mem state)
(asi := ((mem state) asi)(addr := Some val))⦈
in
if (uint asi) = 8 ∨ (uint asi) = 10 then
let asi2 = word_of_int ((uint asi) + 1) in
state1⦇mem := (mem state1)
(asi2 := ((mem state1) asi2)(addr := None))⦈
else if (uint asi) = 9 ∨ (uint asi) = 11 then
let asi2 = word_of_int ((uint asi) - 1) in
state1⦇mem := (mem state1)(asi2 := ((mem state1) asi2)(addr := None))⦈
else state1
"
text ‹An alternative way to write memory. This method insists that
for each address, it can only hold a value in one of ASI = 8,9,10,11.›
definition mem_mod_alt :: "asi_type ⇒ phys_address ⇒ mem_val_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"mem_mod_alt asi addr val state ≡
let state1 = state⦇mem := (mem state)
(asi := ((mem state) asi)(addr := Some val))⦈;
asi8 = word_of_int 8;
asi9 = word_of_int 9;
asi10 = word_of_int 10;
asi11 = word_of_int 11
in
if (uint asi) = 8 then
let state2 = state1⦇mem := (mem state1)
(asi9 := ((mem state1) asi9)(addr := None))⦈;
state3 = state2⦇mem := (mem state2)
(asi10 := ((mem state2) asi10)(addr := None))⦈;
state4 = state3⦇mem := (mem state3)
(asi11 := ((mem state3) asi11)(addr := None))⦈
in
state4
else if (uint asi) = 9 then
let state2 = state1⦇mem := (mem state1)
(asi8 := ((mem state1) asi8)(addr := None))⦈;
state3 = state2⦇mem := (mem state2)
(asi10 := ((mem state2) asi10)(addr := None))⦈;
state4 = state3⦇mem := (mem state3)
(asi11 := ((mem state3) asi11)(addr := None))⦈
in
state4
else if (uint asi) = 10 then
let state2 = state1⦇mem := (mem state1)
(asi9 := ((mem state1) asi9)(addr := None))⦈;
state3 = state2⦇mem := (mem state2)
(asi8 := ((mem state2) asi8)(addr := None))⦈;
state4 = state3⦇mem := (mem state3)
(asi11 := ((mem state3) asi11)(addr := None))⦈
in
state4
else if (uint asi) = 11 then
let state2 = state1⦇mem := (mem state1)
(asi9 := ((mem state1) asi9)(addr := None))⦈;
state3 = state2⦇mem := (mem state2)
(asi10 := ((mem state2) asi10)(addr := None))⦈;
state4 = state3⦇mem := (mem state3)
(asi8 := ((mem state3) asi8)(addr := None))⦈
in
state4
else state1
"
text ‹Given an ASI (word8), an address (word32) addr,
read the 32bit value from the memory addresses
starting from address addr' where addr' = addr
exception that the last two bits are 0's.
That is, read the data from
addr', addr'+1, addr'+2, addr'+3.›
definition mem_val_w32 :: "asi_type ⇒ phys_address ⇒
('a) sparc_state ⇒ word32 option"
where
"mem_val_w32 asi addr state ≡
let addr' = (AND) addr 0b111111111111111111111111111111111100;
addr0 = addr';
addr1 = addr' + 1;
addr2 = addr' + 2;
addr3 = addr' + 3;
r0 = mem_val_alt asi addr0 state;
r1 = mem_val_alt asi addr1 state;
r2 = mem_val_alt asi addr2 state;
r3 = mem_val_alt asi addr3 state
in
if r0 = None ∨ r1 = None ∨ r2 = None ∨ r3 = None then
None
else
let byte0 = case r0 of Some v ⇒ v;
byte1 = case r1 of Some v ⇒ v;
byte2 = case r2 of Some v ⇒ v;
byte3 = case r3 of Some v ⇒ v
in
Some ((OR) ((OR) ((OR) ((ucast(byte0)) << 24)
((ucast(byte1)) << 16))
((ucast(byte2)) << 8))
(ucast(byte3)))
"
text ‹
Let ‹addr'› be ‹addr› with last two bits set to 0's.
Write the 32bit data in the memory address ‹addr'›
(and the following 3 addresses).
‹byte_mask› decides which byte of the 32bits are written.
›
definition mem_mod_w32 :: "asi_type ⇒ phys_address ⇒ word4 ⇒ word32 ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"mem_mod_w32 asi addr byte_mask data_w32 state ≡
let addr' = (AND) addr 0b111111111111111111111111111111111100;
addr0 = (OR) addr' 0b000000000000000000000000000000000000;
addr1 = (OR) addr' 0b000000000000000000000000000000000001;
addr2 = (OR) addr' 0b000000000000000000000000000000000010;
addr3 = (OR) addr' 0b000000000000000000000000000000000011;
byte0 = (ucast (data_w32 >> 24))::mem_val_type;
byte1 = (ucast (data_w32 >> 16))::mem_val_type;
byte2 = (ucast (data_w32 >> 8))::mem_val_type;
byte3 = (ucast data_w32)::mem_val_type;
s0 = if (((AND) byte_mask (0b1000::word4)) >> 3) = 1 then
mem_mod asi addr0 byte0 state
else state;
s1 = if (((AND) byte_mask (0b0100::word4)) >> 2) = 1 then
mem_mod asi addr1 byte1 s0
else s0;
s2 = if (((AND) byte_mask (0b0010::word4)) >> 1) = 1 then
mem_mod asi addr2 byte2 s1
else s1;
s3 = if ((AND) byte_mask (0b0001::word4)) = 1 then
mem_mod asi addr3 byte3 s2
else s2
in
s3
"
text ‹The following functions deal with virtual addresses.
These are based on functions written by David Sanan.›
definition load_word_mem :: "('a) sparc_state ⇒ virtua_address ⇒ asi_type ⇒
machine_word option"
where "load_word_mem state va asi ≡
let pair = (virt_to_phys va (mmu state) (mem state)) in
case pair of
Some pair ⇒ (
if mmu_readable (get_acc_flag (snd pair)) asi then
(mem_val_w32 asi (fst pair) state)
else None)
| None ⇒ None"
definition store_word_mem ::"('a) sparc_state ⇒ virtua_address ⇒ machine_word ⇒
word4 ⇒ asi_type ⇒ ('a) sparc_state option"
where "store_word_mem state va wd byte_mask asi ≡
let pair = (virt_to_phys va (mmu state) (mem state)) in
case pair of
Some pair ⇒ (
if mmu_writable (get_acc_flag (snd pair)) asi then
Some (mem_mod_w32 asi (fst pair) byte_mask wd state)
else None)
| None ⇒ None"
definition icache_val:: "cache_type ⇒ ('a) sparc_state ⇒ mem_val_type option"
where "icache_val c state ≡ icache (cache state) c"
definition dcache_val:: "cache_type ⇒ ('a) sparc_state ⇒ mem_val_type option"
where "dcache_val c state ≡ dcache (cache state) c"
definition icache_mod :: "cache_type ⇒ mem_val_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "icache_mod c val state ≡
state⦇cache := ((cache state)
⦇icache := (icache (cache state))(c := Some val)⦈)⦈
"
definition dcache_mod :: "cache_type ⇒ mem_val_type ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "dcache_mod c val state ≡
state⦇cache := ((cache state)
⦇dcache := (dcache (cache state))(c := Some val)⦈)⦈
"
text ‹Check if the memory address is in the cache or not.›
definition icache_miss :: "virtua_address ⇒ ('a) sparc_state ⇒ bool"
where
"icache_miss addr state ≡
let line_len = 12;
tag = (ucast (addr >> line_len))::cache_tag;
line = (ucast (0b0::word1))::cache_line_size
in
if (icache_val (tag,line) state) = None then True
else False
"
text ‹Check if the memory address is in the cache or not.›
definition dcache_miss :: "virtua_address ⇒ ('a) sparc_state ⇒ bool"
where
"dcache_miss addr state ≡
let line_len = 12;
tag = (ucast (addr >> line_len))::cache_tag;
line = (ucast (0b0::word1))::cache_line_size
in
if (dcache_val (tag,line) state) = None then True
else False
"
definition read_data_cache:: "('a) sparc_state ⇒ virtua_address ⇒ machine_word option"
where "read_data_cache state va ≡
let tag = (ucast (va >> 12))::word20;
offset0 = (AND) ((ucast va)::word12) 0b111111111100;
offset1 = (OR) offset0 0b000000000001;
offset2 = (OR) offset0 0b000000000010;
offset3 = (OR) offset0 0b000000000011;
r0 = dcache_val (tag,offset0) state;
r1 = dcache_val (tag,offset1) state;
r2 = dcache_val (tag,offset2) state;
r3 = dcache_val (tag,offset3) state
in
if r0 = None ∨ r1 = None ∨ r2 = None ∨ r3 = None then
None
else
let byte0 = case r0 of Some v ⇒ v;
byte1 = case r1 of Some v ⇒ v;
byte2 = case r2 of Some v ⇒ v;
byte3 = case r3 of Some v ⇒ v
in
Some ((OR) ((OR) ((OR) ((ucast(byte0)) << 24)
((ucast(byte1)) << 16))
((ucast(byte2)) << 8))
(ucast(byte3)))
"
definition read_instr_cache:: "('a) sparc_state ⇒ virtua_address ⇒ machine_word option"
where "read_instr_cache state va ≡
let tag = (ucast (va >> 12))::word20;
offset0 = (AND) ((ucast va)::word12) 0b111111111100;
offset1 = (OR) offset0 0b000000000001;
offset2 = (OR) offset0 0b000000000010;
offset3 = (OR) offset0 0b000000000011;
r0 = icache_val (tag,offset0) state;
r1 = icache_val (tag,offset1) state;
r2 = icache_val (tag,offset2) state;
r3 = icache_val (tag,offset3) state
in
if r0 = None ∨ r1 = None ∨ r2 = None ∨ r3 = None then
None
else
let byte0 = case r0 of Some v ⇒ v;
byte1 = case r1 of Some v ⇒ v;
byte2 = case r2 of Some v ⇒ v;
byte3 = case r3 of Some v ⇒ v
in
Some ((OR) ((OR) ((OR) ((ucast(byte0)) << 24)
((ucast(byte1)) << 16))
((ucast(byte2)) << 8))
(ucast(byte3)))
"
definition add_data_cache :: "('a) sparc_state ⇒ virtua_address ⇒ machine_word ⇒
word4 ⇒ ('a) sparc_state"
where
"add_data_cache state va word byte_mask ≡
let tag = (ucast (va >> 12))::word20;
offset0 = (AND) ((ucast va)::word12) 0b111111111100;
offset1 = (OR) offset0 0b000000000001;
offset2 = (OR) offset0 0b000000000010;
offset3 = (OR) offset0 0b000000000011;
byte0 = (ucast (word >> 24))::mem_val_type;
byte1 = (ucast (word >> 16))::mem_val_type;
byte2 = (ucast (word >> 8))::mem_val_type;
byte3 = (ucast word)::mem_val_type;
s0 = if (((AND) byte_mask (0b1000::word4)) >> 3) = 1 then
dcache_mod (tag,offset0) byte0 state
else state;
s1 = if (((AND) byte_mask (0b0100::word4)) >> 2) = 1 then
dcache_mod (tag,offset1) byte1 s0
else s0;
s2 = if (((AND) byte_mask (0b0010::word4)) >> 1) = 1 then
dcache_mod (tag,offset2) byte2 s1
else s1;
s3 = if ((AND) byte_mask (0b0001::word4)) = 1 then
dcache_mod (tag,offset3) byte3 s2
else s2
in s3
"
definition add_instr_cache :: "('a) sparc_state ⇒ virtua_address ⇒ machine_word ⇒
word4 ⇒ ('a) sparc_state"
where
"add_instr_cache state va word byte_mask ≡
let tag = (ucast (va >> 12))::word20;
offset0 = (AND) ((ucast va)::word12) 0b111111111100;
offset1 = (OR) offset0 0b000000000001;
offset2 = (OR) offset0 0b000000000010;
offset3 = (OR) offset0 0b000000000011;
byte0 = (ucast (word >> 24))::mem_val_type;
byte1 = (ucast (word >> 16))::mem_val_type;
byte2 = (ucast (word >> 8))::mem_val_type;
byte3 = (ucast word)::mem_val_type;
s0 = if (((AND) byte_mask (0b1000::word4)) >> 3) = 1 then
icache_mod (tag,offset0) byte0 state
else state;
s1 = if (((AND) byte_mask (0b0100::word4)) >> 2) = 1 then
icache_mod (tag,offset1) byte1 s0
else s0;
s2 = if (((AND) byte_mask (0b0010::word4)) >> 1) = 1 then
icache_mod (tag,offset2) byte2 s1
else s1;
s3 = if ((AND) byte_mask (0b0001::word4)) = 1 then
icache_mod (tag,offset3) byte3 s2
else s2
in s3
"
definition empty_cache ::"cache_context" where "empty_cache c ≡ None"
definition flush_data_cache:: "('a) sparc_state ⇒ ('a) sparc_state" where
"flush_data_cache state ≡ state⦇cache := ((cache state)⦇dcache := empty_cache⦈)⦈"
definition flush_instr_cache:: "('a) sparc_state ⇒ ('a) sparc_state" where
"flush_instr_cache state ≡ state⦇cache := ((cache state)⦇icache := empty_cache⦈)⦈"
definition flush_cache_all:: "('a) sparc_state ⇒ ('a) sparc_state" where
"flush_cache_all state ≡ state⦇cache := ((cache state)⦇
icache := empty_cache, dcache := empty_cache⦈)⦈"
text ‹Check if the FI or FD bit of CCR is 1.
If FI is 1 then flush instruction cache.
If FD is 1 then flush data cache.›
definition ccr_flush :: "('a) sparc_state ⇒ ('a) sparc_state"
where
"ccr_flush state ≡
let ccr_val = sys_reg_val CCR state;
fi_val = ((AND) ccr_val (0b00000000001000000000000000000000)) >> 21;
fd_val = ((AND) ccr_val (0b00000000010000000000000000000000)) >> 22;
state1 = (if fi_val = 1 then flush_instr_cache state else state)
in
if fd_val = 1 then flush_data_cache state1 else state1"
definition get_delayed_pool :: "('a) sparc_state ⇒ delayed_write_pool"
where "get_delayed_pool state ≡ dwrite state"
definition exe_pool :: "(int × reg_type × CPU_register) ⇒ (int × reg_type × CPU_register)"
where "exe_pool w ≡ case w of (n,v,c) ⇒ ((n-1),v,c)"
text ‹Minus 1 to the delayed count for all the members in the set.
Assuming all members have delay > 0.›
primrec delayed_pool_minus :: "delayed_write_pool ⇒ delayed_write_pool"
where
"delayed_pool_minus [] = []"
|
"delayed_pool_minus (x#xs) = (exe_pool x)#(delayed_pool_minus xs)"
text ‹Add a delayed-write to the pool.›
definition delayed_pool_add :: "(int × reg_type × CPU_register) ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"delayed_pool_add dw s ≡
let (i,v,cr) = dw in
if i = 0 then
cpu_reg_mod v cr s
else
let curr_pool = get_delayed_pool s in
s⦇dwrite := curr_pool@[dw]⦈"
text ‹Remove a delayed-write from the pool.
Assume that the delayed-write to be removed has delay 0.
i.e., it has been executed.›
definition delayed_pool_rm :: "(int × reg_type × CPU_register) ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where
"delayed_pool_rm dw s ≡
let curr_pool = get_delayed_pool s in
case dw of (n,v,cr) ⇒
(if n = 0 then
s⦇dwrite := List.remove1 dw curr_pool⦈
else s)
"
text ‹Remove all the entries with delay = 0, i.e., those that are written.›
primrec delayed_pool_rm_written :: "delayed_write_pool ⇒ delayed_write_pool"
where
"delayed_pool_rm_written [] = []"
|
"delayed_pool_rm_written (x#xs) =
(if fst x = 0 then delayed_pool_rm_written xs else x#(delayed_pool_rm_written xs))
"
definition annul_val :: "('a) sparc_state ⇒ bool"
where "annul_val state ≡ get_annul (state_var state)"
definition annul_mod :: "bool ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "annul_mod b s ≡ s⦇state_var := write_annul b (state_var s)⦈"
definition reset_trap_val :: "('a) sparc_state ⇒ bool"
where "reset_trap_val state ≡ get_reset_trap (state_var state)"
definition reset_trap_mod :: "bool ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "reset_trap_mod b s ≡ s⦇state_var := write_reset_trap b (state_var s)⦈"
definition exe_mode_val :: "('a) sparc_state ⇒ bool"
where "exe_mode_val state ≡ get_exe_mode (state_var state)"
definition exe_mode_mod :: "bool ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "exe_mode_mod b s ≡ s⦇state_var := write_exe_mode b (state_var s)⦈"
definition reset_mode_val :: "('a) sparc_state ⇒ bool"
where "reset_mode_val state ≡ get_reset_mode (state_var state)"
definition reset_mode_mod :: "bool ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "reset_mode_mod b s ≡ s⦇state_var := write_reset_mode b (state_var s)⦈"
definition err_mode_val :: "('a) sparc_state ⇒ bool"
where "err_mode_val state ≡ get_err_mode (state_var state)"
definition err_mode_mod :: "bool ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "err_mode_mod b s ≡ s⦇state_var := write_err_mode b (state_var s)⦈"
definition ticc_trap_type_val :: "('a) sparc_state ⇒ word7"
where "ticc_trap_type_val state ≡ get_ticc_trap_type (state_var state)"
definition ticc_trap_type_mod :: "word7 ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "ticc_trap_type_mod w s ≡ s⦇state_var := write_ticc_trap_type w (state_var s)⦈"
definition interrupt_level_val :: "('a) sparc_state ⇒ word3"
where "interrupt_level_val state ≡ get_interrupt_level (state_var state)"
definition interrupt_level_mod :: "word3 ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "interrupt_level_mod w s ≡ s⦇state_var := write_interrupt_level w (state_var s)⦈"
definition store_barrier_pending_val :: "('a) sparc_state ⇒ bool"
where "store_barrier_pending_val state ≡
get_store_barrier_pending (state_var state)"
definition store_barrier_pending_mod :: "bool ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "store_barrier_pending_mod w s ≡
s⦇state_var := write_store_barrier_pending w (state_var s)⦈"
definition pb_block_ldst_byte_val :: "virtua_address ⇒ ('a) sparc_state
⇒ bool"
where "pb_block_ldst_byte_val add state ≡
(atm_ldst_byte (state_var state)) add"
definition pb_block_ldst_byte_mod :: "virtua_address ⇒ bool ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "pb_block_ldst_byte_mod add b s ≡
s⦇state_var := ((state_var s)
⦇atm_ldst_byte := (atm_ldst_byte (state_var s))(add := b)⦈)⦈"
text ‹We only read the address such that add mod 4 = 0.
add mod 4 represents the current word.›
definition pb_block_ldst_word_val :: "virtua_address ⇒ ('a) sparc_state
⇒ bool"
where "pb_block_ldst_word_val add state ≡
let add0 = ((AND) add (0b11111111111111111111111111111100::word32)) in
(atm_ldst_word (state_var state)) add0"
text ‹We only write the address such that add mod 4 = 0.
add mod 4 represents the current word.›
definition pb_block_ldst_word_mod :: "virtua_address ⇒ bool ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "pb_block_ldst_word_mod add b s ≡
let add0 = ((AND) add (0b11111111111111111111111111111100::word32)) in
s⦇state_var := ((state_var s)
⦇atm_ldst_word := (atm_ldst_word (state_var s))(add0 := b)⦈)⦈"
definition get_trap_set :: "('a) sparc_state ⇒ Trap set"
where "get_trap_set state ≡ (traps state)"
definition add_trap_set :: "Trap ⇒ ('a) sparc_state ⇒ ('a) sparc_state"
where "add_trap_set t s ≡ s⦇traps := (traps s) ∪ {t}⦈"
definition emp_trap_set :: "('a) sparc_state ⇒ ('a) sparc_state"
where "emp_trap_set s ≡ s⦇traps := {}⦈"
definition state_undef:: "('a) sparc_state ⇒ bool"
where "state_undef state ≡ (undef state)"
text ‹The ‹memory_read› interface that conforms with the SPARCv8 manual.›
definition memory_read :: "asi_type ⇒ virtua_address ⇒
('a) sparc_state ⇒
((word32 option) × ('a) sparc_state)"
where "memory_read asi addr state ≡
let asi_int = uint asi in
if asi_int = 1 then
let r1 = load_word_mem state addr (word_of_int 8) in
if r1 = None then
let r2 = load_word_mem state addr (word_of_int 10) in
if r2 = None then
(None,state)
else (r2,state)
else (r1,state)
else if asi_int = 2 then
if uint addr = 0 then
((Some (sys_reg_val CCR state)), state)
else if uint addr = 8 then
((Some (sys_reg_val ICCR state)), state)
else if uint addr = 12 then
((Some (sys_reg_val DCCR state)), state)
else
(None, state)
else if asi_int ∈ {8,9} then
let ccr_val = (sys_reg state) CCR in
if ccr_val AND 1 ≠ 0 then
let data = load_word_mem state addr asi in
case data of
Some w ⇒ (Some w,(add_instr_cache state addr w (0b1111::word4)))
|None ⇒ (None, state)
else
((load_word_mem state addr asi),state)
else if asi_int ∈ {10,11} then
let ccr_val = (sys_reg state) CCR in
if ccr_val AND 1 ≠ 0 then
let data = load_word_mem state addr asi in
case data of
Some w ⇒ (Some w,(add_data_cache state addr w (0b1111::word4)))
|None ⇒ (None, state)
else
((load_word_mem state addr asi),state)
else if asi_int = 13 then
let cache_result = read_instr_cache state addr in
case cache_result of
Some w ⇒ (Some w, state)
|None ⇒ (None, state)
else if asi_int = 15 then
let cache_result = read_data_cache state addr in
case cache_result of
Some w ⇒ (Some w, state)
|None ⇒ (None, state)
else if asi_int ∈ {16,17} then
(None, state)
else if asi_int ∈ {20,21} then
(None, state)
else if asi_int = 24 then
(None, state)
else if asi_int = 25 then
((mmu_reg_val (mmu state) addr), state)
else if asi_int = 28 then
((mem_val_w32 asi (ucast addr) state), state)
else if asi_int = 29 then
(None, state)
else
(None, state)
"
text ‹Get the value of a memory address and an ASI.›
definition mem_val_asi:: "asi_type ⇒ phys_address ⇒
('a) sparc_state ⇒ mem_val_type option"
where "mem_val_asi asi add state ≡ (mem state) asi add"
text ‹Check if an address is used in ASI 9 or 11.›
definition sup_addr :: "phys_address ⇒ ('a) sparc_state ⇒ bool"
where
"sup_addr addr state ≡
let addr' = (AND) addr 0b111111111111111111111111111111111100;
addr0 = (OR) addr' 0b000000000000000000000000000000000000;
addr1 = (OR) addr' 0b000000000000000000000000000000000001;
addr2 = (OR) addr' 0b000000000000000000000000000000000010;
addr3 = (OR) addr' 0b000000000000000000000000000000000011;
r0 = mem_val_asi 9 addr0 state;
r1 = mem_val_asi 9 addr1 state;
r2 = mem_val_asi 9 addr2 state;
r3 = mem_val_asi 9 addr3 state;
r4 = mem_val_asi 11 addr0 state;
r5 = mem_val_asi 11 addr1 state;
r6 = mem_val_asi 11 addr2 state;
r7 = mem_val_asi 11 addr3 state
in
if r0 = None ∧ r1 = None ∧ r2 = None ∧ r3 = None ∧
r4 = None ∧ r5 = None ∧ r6 = None ∧ r7 = None
then False
else True
"
text ‹The ‹memory_write› interface that conforms with SPARCv8 manual.›
text ‹LEON3 forbids user to write an address in ASI 9 and 11.›
definition memory_write_asi :: "asi_type ⇒ virtua_address ⇒ word4 ⇒ word32 ⇒
('a) sparc_state ⇒
('a) sparc_state option"
where
"memory_write_asi asi addr byte_mask data_w32 state ≡
let asi_int = uint asi;
psr_val = cpu_reg_val PSR state;
s_val = get_S psr_val
in
if asi_int = 1 then
store_word_mem state addr data_w32 byte_mask (word_of_int 10)
else if asi_int = 2 then
if uint addr = 0 then
let s1 = (sys_reg_mod data_w32 CCR state) in
Some (ccr_flush s1)
else if uint addr = 8 then
Some (sys_reg_mod data_w32 ICCR state)
else if uint addr = 12 then
Some (sys_reg_mod data_w32 DCCR state)
else
None
else if asi_int ∈ {8,9} then
let ns = add_instr_cache state addr data_w32 byte_mask in
store_word_mem ns addr data_w32 byte_mask asi
else if asi_int ∈ {10,11} then
let ns = add_data_cache state addr data_w32 byte_mask in
store_word_mem ns addr data_w32 byte_mask asi
else if asi_int = 13 then
Some (add_instr_cache state addr data_w32 (0b1111::word4))
else if asi_int = 15 then
Some (add_data_cache state addr data_w32 (0b1111::word4))
else if asi_int = 16 then
Some (flush_instr_cache state)
else if asi_int = 17 then
Some (flush_data_cache state)
else if asi_int ∈ {20,21} then
None
else if asi_int = 24 then
Some (flush_cache_all state)
else if asi_int = 25 then
let mmu_state' = mmu_reg_mod (mmu state) addr data_w32 in
case mmu_state' of
Some mmus ⇒ Some (state⦇mmu := mmus⦈)
|None ⇒ None
else if asi_int = 28 then
Some (mem_mod_w32 asi (ucast addr) byte_mask data_w32 state)
else if asi_int = 29 then
None
else
None
"
definition memory_write :: "asi_type ⇒ virtua_address ⇒ word4 ⇒ word32 ⇒
('a) sparc_state ⇒
('a) sparc_state option"
where
"memory_write asi addr byte_mask data_w32 state ≡
let result = memory_write_asi asi addr byte_mask data_w32 state in
case result of
None ⇒ None
| Some s1 ⇒ Some (store_barrier_pending_mod False s1)"
text ‹monad for sequential operations over the register representation›
type_synonym ('a,'e) sparc_state_monad = "(('a) sparc_state,'e) det_monad"
text ‹Given a word32 value, a cpu register,
write the value in the cpu register.›
definition write_cpu :: "word32 ⇒ CPU_register ⇒ ('a,unit) sparc_state_monad"
where "write_cpu w cr ≡
do
modify (λs. (cpu_reg_mod w cr s));
return ()
od"
definition write_cpu_tt :: "word8 ⇒ ('a,unit) sparc_state_monad"
where "write_cpu_tt w ≡
do
tbr_val ← gets (λs. (cpu_reg_val TBR s));
new_tbr_val ← gets (λs. (write_tt w tbr_val));
write_cpu new_tbr_val TBR;
return ()
od"
text ‹Given a word32 value, a word4 window, a user register,
write the value in the user register.
N.B. CWP is a 5 bit value, but we only use the last 4 bits,
since there are only 16 windows.›
definition write_reg :: "word32 ⇒ ('a::len) word ⇒ user_reg_type ⇒
('a,unit) sparc_state_monad"
where "write_reg w win ur ≡
do
modify (λs.(user_reg_mod w win ur s));
return ()
od"
definition set_annul :: "bool ⇒ ('a,unit) sparc_state_monad"
where "set_annul b ≡
do
modify (λs. (annul_mod b s));
return ()
od"
definition set_reset_trap :: "bool ⇒ ('a,unit) sparc_state_monad"
where "set_reset_trap b ≡
do
modify (λs. (reset_trap_mod b s));
return ()
od"
definition set_exe_mode :: "bool ⇒ ('a,unit) sparc_state_monad"
where "set_exe_mode b ≡
do
modify (λs. (exe_mode_mod b s));
return ()
od"
definition set_reset_mode :: "bool ⇒ ('a,unit) sparc_state_monad"
where "set_reset_mode b ≡
do
modify (λs. (reset_mode_mod b s));
return ()
od"
definition set_err_mode :: "bool ⇒ ('a,unit) sparc_state_monad"
where "set_err_mode b ≡
do
modify (λs. (err_mode_mod b s));
return ()
od"
fun get_delayed_0 :: "(int × reg_type × CPU_register) list ⇒
(int × reg_type × CPU_register) list"
where
"get_delayed_0 [] = []"
|
"get_delayed_0 (x # xs) =
(if fst x = 0 then x # (get_delayed_0 xs)
else get_delayed_0 xs)"
text ‹Get a list of delayed-writes with delay 0.›
definition get_delayed_write :: "delayed_write_pool ⇒ (int × reg_type × CPU_register) list"
where
"get_delayed_write dwp ≡ get_delayed_0 dwp"
definition delayed_write :: "(int × reg_type × CPU_register) ⇒ ('a) sparc_state ⇒
('a) sparc_state"
where "delayed_write dw s ≡
let (n,v,r) = dw in
if n = 0 then
cpu_reg_mod v r s
else s"
primrec delayed_write_all :: "(int × reg_type × CPU_register) list ⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "delayed_write_all [] s = s"
|"delayed_write_all (x # xs) s =
delayed_write_all xs (delayed_write x s)"
primrec delayed_pool_rm_list :: "(int × reg_type × CPU_register) list⇒
('a) sparc_state ⇒ ('a) sparc_state"
where "delayed_pool_rm_list [] s = s"
|"delayed_pool_rm_list (x # xs) s =
delayed_pool_rm_list xs (delayed_pool_rm x s)"
definition delayed_pool_write :: "('a) sparc_state ⇒ ('a) sparc_state"
where "delayed_pool_write s ≡
let dwp0 = get_delayed_pool s;
dwp1 = delayed_pool_minus dwp0;
wl = get_delayed_write dwp1;
s1 = delayed_write_all wl s;
s2 = delayed_pool_rm_list wl s1
in s2"
definition raise_trap :: "Trap ⇒ ('a,unit) sparc_state_monad"
where "raise_trap t ≡
do
modify (λs. (add_trap_set t s));
return ()
od"
end
Theory Sparc_Instruction
section ‹SPARC instruction model›
theory Sparc_Instruction
imports Main Sparc_Types Sparc_State "HOL-Eisbach.Eisbach_Tools"
begin
text‹
This theory provides a formal model for assembly instruction to be executed in the model.
An instruction is defined as a tuple composed of a @{term sparc_operation} element,
defining the operation the instruction carries out, and a list of operands
@{term inst_operand}. @{term inst_operand} can be a user register @{term user_reg}
or a memory address @{term mem_add_type}.
›
datatype inst_operand =
W5 word5
|W30 word30
|W22 word22
|Cond word4
|Flag word1
|Asi asi_type
|Simm13 word13
|Opf word9
|Imm7 word7
primrec get_operand_w5::"inst_operand ⇒ word5"
where "get_operand_w5 (W5 r) = r"
primrec get_operand_w30::"inst_operand ⇒ word30"
where "get_operand_w30 (W30 r) = r"
primrec get_operand_w22::"inst_operand ⇒ word22"
where "get_operand_w22 (W22 r) = r"
primrec get_operand_cond::"inst_operand ⇒ word4"
where "get_operand_cond (Cond r) = r"
primrec get_operand_flag::"inst_operand ⇒ word1"
where "get_operand_flag (Flag r) = r"
primrec get_operand_asi::"inst_operand ⇒ asi_type"
where "get_operand_asi (Asi r) = r"
primrec get_operand_simm13::"inst_operand ⇒ word13"
where "get_operand_simm13 (Simm13 r) = r"
primrec get_operand_opf::"inst_operand ⇒ word9"
where "get_operand_opf (Opf r) = r"
primrec get_operand_imm7:: "inst_operand ⇒ word7"
where "get_operand_imm7 (Imm7 r) = r"
type_synonym instruction = "(sparc_operation × inst_operand list)"
definition get_op::"word32 ⇒ int"
where "get_op w ≡ uint (w >> 30)"
definition get_op2::"word32 ⇒ int"
where "get_op2 w ≡
let mask_op2 = 0b00000001110000000000000000000000 in
uint (((AND) mask_op2 w) >> 22)"
definition get_op3::"word32 ⇒ int"
where "get_op3 w ≡
let mask_op3 = 0b00000001111110000000000000000000 in
uint (((AND) mask_op3 w) >> 19)"
definition get_disp30::"word32 ⇒ int"
where "get_disp30 w ≡
let mask_disp30 = 0b00111111111111111111111111111111 in
uint ((AND) mask_disp30 w)"
definition get_a::"word32 ⇒ int"
where "get_a w ≡
let mask_a = 0b00100000000000000000000000000000 in
uint (((AND) mask_a w) >> 29)"
definition get_cond::"word32 ⇒ int"
where "get_cond w ≡
let mask_cond = 0b00011110000000000000000000000000 in
uint (((AND) mask_cond w) >> 25)"
definition get_disp_imm22::"word32 ⇒ int"
where "get_disp_imm22 w ≡
let mask_disp_imm22 = 0b00000000001111111111111111111111 in
uint ((AND) mask_disp_imm22 w)"
definition get_rd::"word32 ⇒ int"
where "get_rd w ≡
let mask_rd = 0b00111110000000000000000000000000 in
uint (((AND) mask_rd w) >> 25)"
definition get_rs1::"word32 ⇒ int"
where "get_rs1 w ≡
let mask_rs1 = 0b00000000000001111100000000000000 in
uint (((AND) mask_rs1 w) >> 14)"
definition get_i::"word32 ⇒ int"
where "get_i w ≡
let mask_i = 0b00000000000000000010000000000000 in
uint (((AND) mask_i w) >> 13)"
definition get_opf::"word32 ⇒ int"
where "get_opf w ≡
let mask_opf = 0b00000000000000000011111111100000 in
uint (((AND) mask_opf w) >> 5)"
definition get_rs2::"word32 ⇒ int"
where "get_rs2 w ≡
let mask_rs2 = 0b00000000000000000000000000011111 in
uint ((AND) mask_rs2 w)"
definition get_simm13::"word32 ⇒ int"
where "get_simm13 w ≡
let mask_simm13 = 0b00000000000000000001111111111111 in
uint ((AND) mask_simm13 w)"
definition get_asi::"word32 ⇒ int"
where "get_asi w ≡
let mask_asi = 0b00000000000000000001111111100000 in
uint (((AND) mask_asi w) >> 5)"
definition get_trap_cond:: "word32 ⇒ int"
where "get_trap_cond w ≡
let mask_cond = 0b00011110000000000000000000000000 in
uint (((AND) mask_cond w) >> 25)"
definition get_trap_imm7:: "word32 ⇒ int"
where "get_trap_imm7 w ≡
let mask_imm7 = 0b00000000000000000000000001111111 in
uint ((AND) mask_imm7 w)"
definition parse_instr_f1::"word32 ⇒
(Exception list + instruction)"
where
"parse_instr_f1 w ≡
Inr (call_type CALL,[W30 (word_of_int (get_disp30 w))])"
definition parse_instr_f2::"word32 ⇒
(Exception list + instruction)"
where "parse_instr_f2 w ≡
let op2 = get_op2 w in
if op2 = uint(0b100::word3) then
let rd = get_rd w in
let imm22 = get_disp_imm22 w in
if rd = 0 ∧ imm22 = 0 then
Inr (nop_type NOP,[])
else
Inr (sethi_type SETHI,[(W22 (word_of_int imm22)),
(W5 (word_of_int rd))])
else if op2 = uint(0b010::word3) then
let cond = get_cond w in
let flaga = Flag (word_of_int (get_a w)) in
let disp22 = W22 (word_of_int (get_disp_imm22 w)) in
if cond = uint(0b0001::word4) then
Inr (bicc_type BE,[flaga,disp22])
else if cond = uint(0b1001::word4) then
Inr (bicc_type BNE,[flaga,disp22])
else if cond = uint(0b1100::word4) then
Inr (bicc_type BGU,[flaga,disp22])
else if cond = uint(0b0010::word4) then
Inr (bicc_type BLE,[flaga,disp22])
else if cond = uint(0b0011::word4) then
Inr (bicc_type BL,[flaga,disp22])
else if cond = uint(0b1011::word4) then
Inr (bicc_type BGE,[flaga,disp22])
else if cond = uint(0b0110::word4) then
Inr (bicc_type BNEG,[flaga,disp22])
else if cond = uint(0b1010::word4) then
Inr (bicc_type BG,[flaga,disp22])
else if cond = uint(0b0101::word4) then
Inr (bicc_type BCS,[flaga,disp22])
else if cond = uint(0b0100::word4) then
Inr (bicc_type BLEU,[flaga,disp22])
else if cond = uint(0b1101::word4) then
Inr (bicc_type BCC,[flaga,disp22])
else if cond = uint(0b1000::word4) then
Inr (bicc_type BA,[flaga,disp22])
else if cond = uint(0b0000::word4) then
Inr (bicc_type BN,[flaga,disp22])
else if cond = uint(0b1110::word4) then
Inr (bicc_type BPOS,[flaga,disp22])
else if cond = uint(0b1111::word4) then
Inr (bicc_type BVC,[flaga,disp22])
else if cond = uint(0b0111::word4) then
Inr (bicc_type BVS,[flaga,disp22])
else Inl [invalid_cond_f2]
else Inl [invalid_op2_f2]
"
text ‹We don't consider floating-point operations,
so we don't consider the third type of format 3.›
definition parse_instr_f3::"word32 ⇒ (Exception list + instruction)"
where "parse_instr_f3 w ≡
let this_op = get_op w in
let rd = get_rd w in
let op3 = get_op3 w in
let rs1 = get_rs1 w in
let flagi = get_i w in
let asi = get_asi w in
let rs2 = get_rs2 w in
let simm13 = get_simm13 w in
if this_op = uint(0b11::word2) then
if op3 = uint(0b001001::word6) then
if flagi = 1 then
Inr (load_store_type LDSB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDSB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011001::word6) then
Inr (load_store_type LDSBA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001010::word6) then
if flagi = 1 then
Inr (load_store_type LDSH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDSH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011010::word6) then
Inr (load_store_type LDSHA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000001::word6) then
if flagi = 1 then
Inr (load_store_type LDUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010001::word6) then
Inr (load_store_type LDUBA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000010::word6) then
if flagi = 1 then
Inr (load_store_type LDUH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDUH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010010::word6) then
Inr (load_store_type LDUHA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000000::word6) then
if flagi = 1 then
Inr (load_store_type LD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010000::word6) then
Inr (load_store_type LDA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000011::word6) then
if flagi = 1 then
Inr (load_store_type LDD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010011::word6) then
Inr (load_store_type LDDA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001101::word6) then
if flagi = 1 then
Inr (load_store_type LDSTUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type LDSTUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011101::word6) then
Inr (load_store_type LDSTUBA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000101::word6) then
if flagi = 1 then
Inr (load_store_type STB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type STB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010101::word6) then
Inr (load_store_type STBA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000110::word6) then
if flagi = 1 then
Inr (load_store_type STH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type STH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010110::word6) then
Inr (load_store_type STHA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000100::word6) then
if flagi = 1 then
Inr (load_store_type ST,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type ST,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010100::word6) then
Inr (load_store_type STA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000111::word6) then
if flagi = 1 then
Inr (load_store_type STD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type STD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010111::word6) then
Inr (load_store_type STDA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001111::word6) then
if flagi = 1 then
Inr (load_store_type SWAP,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else
Inr (load_store_type SWAP,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011111::word6) then
Inr (load_store_type SWAPA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(Asi (word_of_int asi)),
(W5 (word_of_int rd))])
else Inl [invalid_op3_f3_op11]
else if this_op = uint(0b10::word2) then
if op3 = uint(0b111000::word6) then
if flagi = 0 then
Inr (ctrl_type JMPL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (ctrl_type JMPL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b111001::word6) then
if flagi = 0 then
Inr (ctrl_type RETT,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ctrl_type RETT,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13))])
else if op3 = uint(0b101000::word6) ∧ rs1 ≠ 0 then
if rs1 = uint(0b01111::word6) ∧ rd = 0 then
Inr (load_store_type STBAR,[])
else Inr (sreg_type RDASR,[(W5 (word_of_int rs1)),
(W5 (word_of_int rd))])
else if op3 = uint(0b101000::word6) ∧ rs1 = 0 then
Inr (sreg_type RDY,[(W5 (word_of_int rs1)),
(W5 (word_of_int rd))])
else if op3 = uint(0b101001::word6) then
Inr (sreg_type RDPSR,[(W5 (word_of_int rs1)),
(W5 (word_of_int rd))])
else if op3 = uint(0b101010::word6) then
Inr (sreg_type RDWIM,[(W5 (word_of_int rs1)),
(W5 (word_of_int rd))])
else if op3 = uint(0b101011::word6) then
Inr (sreg_type RDTBR,[(W5 (word_of_int rs1)),
(W5 (word_of_int rd))])
else if op3 = uint(0b110000::word6) ∧ rd ≠ 0 then
if flagi = 0 then
Inr (sreg_type WRASR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (sreg_type WRASR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b110000::word6) ∧ rd = 0 then
if flagi = 0 then
Inr (sreg_type WRY,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (sreg_type WRY,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b110001::word6) then
if flagi = 0 then
Inr (sreg_type WRPSR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (sreg_type WRPSR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b110010::word6) then
if flagi = 0 then
Inr (sreg_type WRWIM,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (sreg_type WRWIM,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b110011::word6) then
if flagi = 0 then
Inr (sreg_type WRTBR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (sreg_type WRTBR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b111011::word6) then
if flagi = 0 then
Inr (load_store_type FLUSH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (load_store_type FLUSH,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13))])
else if op3 = uint(0b000001::word6) then
if flagi = 0 then
Inr (logic_type ANDs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ANDs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010001::word6) then
if flagi = 0 then
Inr (logic_type ANDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ANDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000101::word6) then
if flagi = 0 then
Inr (logic_type ANDN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ANDN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010101::word6) then
if flagi = 0 then
Inr (logic_type ANDNcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ANDNcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000010::word6) then
if flagi = 0 then
Inr (logic_type ORs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ORs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010010::word6) then
if flagi = 0 then
Inr (logic_type ORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000110::word6) then
if flagi = 0 then
Inr (logic_type ORN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ORN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010110::word6) then
if flagi = 0 then
Inr (logic_type ORNcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type ORNcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000011::word6) then
if flagi = 0 then
Inr (logic_type XORs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type XORs,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010011::word6) then
if flagi = 0 then
Inr (logic_type XORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type XORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000111::word6) then
if flagi = 0 then
Inr (logic_type XNOR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type XNOR,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010111::word6) then
if flagi = 0 then
Inr (logic_type XNORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (logic_type XNORcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100101::word6) then
if flagi = 0 then
Inr (shift_type SLL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
let shcnt = rs2 in
Inr (shift_type SLL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int shcnt)),
(W5 (word_of_int rd))])
else if op3 = uint (0b100110::word6) then
if flagi = 0 then
Inr (shift_type SRL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
let shcnt = rs2 in
Inr (shift_type SRL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int shcnt)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100111::word6) then
if flagi = 0 then
Inr (shift_type SRA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
let shcnt = rs2 in
Inr (shift_type SRA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int shcnt)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000000::word6) then
if flagi = 0 then
Inr (arith_type ADD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type ADD,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010000::word6) then
if flagi = 0 then
Inr (arith_type ADDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type ADDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001000::word6) then
if flagi = 0 then
Inr (arith_type ADDX,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type ADDX,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011000::word6) then
if flagi = 0 then
Inr (arith_type ADDXcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type ADDXcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100000::word6) then
if flagi = 0 then
Inr (arith_type TADDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type TADDcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100010::word6) then
if flagi = 0 then
Inr (arith_type TADDccTV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type TADDccTV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b000100::word6) then
if flagi = 0 then
Inr (arith_type SUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SUB,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b010100::word6) then
if flagi = 0 then
Inr (arith_type SUBcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SUBcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001100::word6) then
if flagi = 0 then
Inr (arith_type SUBX,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SUBX,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011100::word6) then
if flagi = 0 then
Inr (arith_type SUBXcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SUBXcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100001::word6) then
if flagi = 0 then
Inr (arith_type TSUBcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type TSUBcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100011::word6) then
if flagi = 0 then
Inr (arith_type TSUBccTV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type TSUBccTV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b100100::word6) then
if flagi = 0 then
Inr (arith_type MULScc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type MULScc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001010::word6) then
if flagi = 0 then
Inr (arith_type UMUL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type UMUL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011010::word6) then
if flagi = 0 then
Inr (arith_type UMULcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type UMULcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001011::word6) then
if flagi = 0 then
Inr (arith_type SMUL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SMUL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011011::word6) then
if flagi = 0 then
Inr (arith_type SMULcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SMULcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001110::word6) then
if flagi = 0 then
Inr (arith_type UDIV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type UDIV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011110::word6) then
if flagi = 0 then
Inr (arith_type UDIVcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type UDIVcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b001111::word6) then
if flagi = 0 then
Inr (arith_type SDIV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SDIV,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b011111::word6) then
if flagi = 0 then
Inr (arith_type SDIVcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (arith_type SDIVcc,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b111100::word6) then
if flagi = 0 then
Inr (ctrl_type SAVE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (ctrl_type SAVE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b111101::word6) then
if flagi = 0 then
Inr (ctrl_type RESTORE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2)),
(W5 (word_of_int rd))])
else
Inr (ctrl_type RESTORE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Simm13 (word_of_int simm13)),
(W5 (word_of_int rd))])
else if op3 = uint(0b111010::word6) then
let trap_cond = get_trap_cond w in
let trap_imm7 = get_trap_imm7 w in
if trap_cond = uint(0b1000::word4) then
if flagi = 0 then
Inr (ticc_type TA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TA,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0000::word4) then
if flagi = 0 then
Inr (ticc_type TN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TN,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1001::word4) then
if flagi = 0 then
Inr (ticc_type TNE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TNE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0001::word4) then
if flagi = 0 then
Inr (ticc_type TE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1010::word4) then
if flagi = 0 then
Inr (ticc_type TG,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TG,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0010::word4) then
if flagi = 0 then
Inr (ticc_type TLE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TLE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1011::word4) then
if flagi = 0 then
Inr (ticc_type TGE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TGE,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0011::word4) then
if flagi = 0 then
Inr (ticc_type TL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TL,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1100::word4) then
if flagi = 0 then
Inr (ticc_type TGU,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TGU,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0100::word4) then
if flagi = 0 then
Inr (ticc_type TLEU,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TLEU,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1101::word4) then
if flagi = 0 then
Inr (ticc_type TCC,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TCC,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0101::word4) then
if flagi = 0 then
Inr (ticc_type TCS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TCS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1110::word4) then
if flagi = 0 then
Inr (ticc_type TPOS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TPOS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0110::word4) then
if flagi = 0 then
Inr (ticc_type TNEG,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TNEG,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b1111::word4) then
if flagi = 0 then
Inr (ticc_type TVC,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TVC,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else if trap_cond = uint(0b0111::word4) then
if flagi = 0 then
Inr (ticc_type TVS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(W5 (word_of_int rs2))])
else
Inr (ticc_type TVS,[(Flag (word_of_int flagi)),
(W5 (word_of_int rs1)),
(Imm7 (word_of_int trap_imm7))])
else Inl [invalid_trap_cond]
else Inl [invalid_op3_f3_op10]
else Inl [invalid_op_f3]
"
text ‹Read the word32 value from the Program Counter in the current state.
Find the instruction in the memory address of the word32 value.
Return a word32 value of the insturction.›
definition fetch_instruction::"('a) sparc_state ⇒
(Exception list + word32)"
where "fetch_instruction s ≡
let pc_val = cpu_reg_val PC s;
psr_val = cpu_reg_val PSR s;
s_val = get_S psr_val;
asi = if s_val = 0 then word_of_int 8 else word_of_int 9
in
if uint((AND) (0b00000000000000000000000000000011) pc_val) = 0 then
let (mem_result,n_s) = memory_read asi pc_val s in
case mem_result of
None ⇒ Inl [fetch_instruction_error]
|Some v ⇒ Inr v
else Inl [fetch_instruction_error]
"
text ‹Decode the word32 value of an instruction into
the name of the instruction and its operands.›
definition decode_instruction::"word32 ⇒
Exception list + instruction"
where "decode_instruction w ≡
let this_op = get_op w in
if this_op = uint(0b01::word2) then
parse_instr_f1 w
else if this_op = uint(0b00::word2) then
parse_instr_f2 w
else
parse_instr_f3 w
"
text ‹Get the current window from the PSR›
definition get_curr_win::"unit ⇒ ('a,('a::len window_size)) sparc_state_monad"
where "get_curr_win _ ≡
do
curr_win ← gets (λs. (ucast (get_CWP (cpu_reg_val PSR s))));
return curr_win
od"
text ‹Operational semantics for CALL›
definition call_instr::"instruction ⇒ ('a::len,unit) sparc_state_monad"
where "call_instr instr ≡
let op_list = snd instr;
mem_addr = ((ucast (get_operand_w30 (op_list!0)))::word32) << 2
in
do
curr_win ← get_curr_win();
pc_val ← gets (λs. (cpu_reg_val PC s));
npc_val ← gets (λs. (cpu_reg_val nPC s));
write_reg pc_val curr_win (word_of_int 15);
write_cpu npc_val PC;
write_cpu (pc_val + mem_addr) nPC;
return ()
od"
text‹Evaluate icc based on the bits N, Z, V, C in PSR
and the type of branching instruction.
See Sparcv8 manual Page 178.›
definition eval_icc::"sparc_operation ⇒ word1 ⇒ word1 ⇒ word1 ⇒ word1 ⇒ int"
where
"eval_icc instr_name n_val z_val v_val c_val ≡
if instr_name = bicc_type BNE then
if z_val = 0 then 1 else 0
else if instr_name = bicc_type BE then
if z_val = 1 then 1 else 0
else if instr_name = bicc_type BG then
if ((OR) z_val (n_val XOR v_val)) = 0 then 1 else 0
else if instr_name = bicc_type BLE then
if ((OR) z_val (n_val XOR v_val)) = 1 then 1 else 0
else if instr_name = bicc_type BGE then
if (n_val XOR v_val) = 0 then 1 else 0
else if instr_name = bicc_type BL then
if (n_val XOR v_val) = 1 then 1 else 0
else if instr_name = bicc_type BGU then
if (c_val = 0 ∧ z_val = 0) then 1 else 0
else if instr_name = bicc_type BLEU then
if (c_val = 1 ∨ z_val = 1) then 1 else 0
else if instr_name = bicc_type BCC then
if c_val = 0 then 1 else 0
else if instr_name = bicc_type BCS then
if c_val = 1 then 1 else 0
else if instr_name = bicc_type BNEG then
if n_val = 1 then 1 else 0
else if instr_name = bicc_type BA then 1
else if instr_name = bicc_type BN then 0
else if instr_name = bicc_type BPOS then
if n_val = 0 then 1 else 0
else if instr_name = bicc_type BVC then
if v_val = 0 then 1 else 0
else if instr_name = bicc_type BVS then
if v_val = 1 then 1 else 0
else -1
"
definition branch_instr_sub1:: "sparc_operation ⇒ ('a) sparc_state ⇒ int"
where "branch_instr_sub1 instr_name s ≡
let n_val = get_icc_N ((cpu_reg s) PSR);
z_val = get_icc_Z ((cpu_reg s) PSR);
v_val = get_icc_V ((cpu_reg s) PSR);
c_val = get_icc_C ((cpu_reg s) PSR)
in
eval_icc instr_name n_val z_val v_val c_val"
text ‹Operational semantics for Branching insturctions.
Return exception or a bool value for annulment.
If the bool value is 1, then the delay instruciton
is not executed, otherwise the delay instruction
is executed.›
definition branch_instr::"instruction ⇒ ('a,unit) sparc_state_monad"
where "branch_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
disp22 = get_operand_w22 (op_list!1);
flaga = get_operand_flag (op_list!0)
in
do
icc_val ← gets( λs. (branch_instr_sub1 instr_name s));
npc_val ← gets (λs. (cpu_reg_val nPC s));
pc_val ← gets (λs. (cpu_reg_val PC s));
write_cpu npc_val PC;
if icc_val = 1 then
do
write_cpu (pc_val + (sign_ext24 (((ucast(disp22))::word24) << 2))) nPC;
if (instr_name = bicc_type BA) ∧ (flaga = 1) then
do
set_annul True;
return ()
od
else
return ()
od
else
do
write_cpu (npc_val + 4) nPC;
if flaga = 1 then
do
set_annul True;
return ()
od
else return ()
od
od"
text ‹Operational semantics for NOP›
definition nop_instr::"instruction ⇒ ('a,unit) sparc_state_monad"
where "nop_instr instr ≡ return ()"
text ‹Operational semantics for SETHI›
definition sethi_instr::"instruction ⇒ ('a::len,unit) sparc_state_monad"
where "sethi_instr instr ≡
let op_list = snd instr;
imm22 = get_operand_w22 (op_list!0);
rd = get_operand_w5 (op_list!1)
in
if rd ≠ 0 then
do
curr_win ← get_curr_win();
write_reg (((ucast(imm22))::word32) << 10) curr_win rd;
return ()
od
else return ()
"
text ‹
Get ‹operand2› based on the flag ‹i›, ‹rs1›, ‹rs2›, and ‹simm13›.
If ‹i = 0› then ‹operand2 = r[rs2]›,
else ‹operand2 = sign_ext13(simm13)›.
‹op_list› should be ‹[i,rs1,rs2,…]› or ‹[i,rs1,simm13,…]›.
›
definition get_operand2::"inst_operand list ⇒ ('a::len) sparc_state
⇒ virtua_address"
where "get_operand2 op_list s ≡
let flagi = get_operand_flag (op_list!0);
curr_win = ucast (get_CWP (cpu_reg_val PSR s))
in
if flagi = 0 then
let rs2 = get_operand_w5 (op_list!2);
rs2_val = user_reg_val curr_win rs2 s
in rs2_val
else
let ext_simm13 = sign_ext13 (get_operand_simm13 (op_list!2)) in
ext_simm13
"
text ‹
Get ‹operand2_val› based on the flag ‹i›, ‹rs1›, ‹rs2›, and ‹simm13›.
If ‹i = 0› then ‹operand2_val = uint r[rs2]›,
else ‹operand2_val = sint sign_ext13(simm13)›.
‹op_list› should be ‹[i,rs1,rs2,…]› or ‹[i,rs1,simm13,…]›.
›
definition get_operand2_val::"inst_operand list ⇒ ('a::len) sparc_state ⇒ int"
where "get_operand2_val op_list s ≡
let flagi = get_operand_flag (op_list!0);
curr_win = ucast (get_CWP (cpu_reg_val PSR s))
in
if flagi = 0 then
let rs2 = get_operand_w5 (op_list!2);
rs2_val = user_reg_val curr_win rs2 s
in sint rs2_val
else
let ext_simm13 = sign_ext13 (get_operand_simm13 (op_list!2)) in
sint ext_simm13
"
text ‹
Get the address based on the flag ‹i›, ‹rs1›, ‹rs2›, and ‹simm13›.
If ‹i = 0› then ‹addr = r[rs1] + r[rs2]›,
else ‹addr = r[rs1] + sign_ext13(simm13)›.
‹op_list› should be ‹[i,rs1,rs2,…]› or ‹[i,rs1,simm13,…]›.
›
definition get_addr::"inst_operand list ⇒ ('a::len) sparc_state ⇒ virtua_address"
where "get_addr op_list s ≡
let rs1 = get_operand_w5 (op_list!1);
curr_win = ucast (get_CWP (cpu_reg_val PSR s));
rs1_val = user_reg_val curr_win rs1 s;
op2 = get_operand2 op_list s
in
(rs1_val + op2)
"
text ‹Operational semantics for JMPL›
definition jmpl_instr::"instruction ⇒ ('a::len,unit) sparc_state_monad"
where "jmpl_instr instr ≡
let op_list = snd instr;
rd = get_operand_w5 (op_list!3)
in
do
curr_win ← get_curr_win();
jmp_addr ← gets (λs. (get_addr op_list s));
if ((AND) jmp_addr 0b00000000000000000000000000000011) ≠ 0 then
do
raise_trap mem_address_not_aligned;
return ()
od
else
do
rd_next_val ← gets (λs. (if rd ≠ 0 then
(cpu_reg_val PC s)
else
user_reg_val curr_win rd s));
write_reg rd_next_val curr_win rd;
npc_val ← gets (λs. (cpu_reg_val nPC s));
write_cpu npc_val PC;
write_cpu jmp_addr nPC;
return ()
od
od"
text ‹Operational semantics for RETT›
definition rett_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "rett_instr instr ≡
let op_list = snd instr in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
curr_win ← gets (λs. (get_CWP (cpu_reg_val PSR s)));
new_cwp ← gets (λs. (word_of_int (((uint curr_win) + 1) mod NWINDOWS)));
new_cwp_int ← gets (λs. ((uint curr_win) + 1) mod NWINDOWS);
addr ← gets (λs. (get_addr op_list s));
et_val ← gets (λs. ((ucast (get_ET psr_val))::word1));
s_val ← gets (λs. ((ucast (get_S psr_val))::word1));
ps_val ← gets (λs. ((ucast (get_PS psr_val))::word1));
wim_val ← gets (λs. (cpu_reg_val WIM s));
npc_val ← gets (λs. (cpu_reg_val nPC s));
if et_val = 1 then
if s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else
do
raise_trap illegal_instruction;
return ()
od
else if s_val = 0 then
do
write_cpu_tt (0b00000011::word8);
set_exe_mode False;
set_err_mode True;
raise_trap privileged_instruction;
fail ()
od
else if (get_WIM_bit (nat new_cwp_int) wim_val) ≠ 0 then
do
write_cpu_tt (0b00000110::word8);
set_exe_mode False;
set_err_mode True;
raise_trap window_underflow;
fail ()
od
else if ((AND) addr (0b00000000000000000000000000000011::word32)) ≠ 0 then
do
write_cpu_tt (0b00000111::word8);
set_exe_mode False;
set_err_mode True;
raise_trap mem_address_not_aligned;
fail ()
od
else
do
write_cpu npc_val PC;
write_cpu addr nPC;
new_psr_val ← gets (λs. (update_PSR_rett new_cwp 1 ps_val psr_val));
write_cpu new_psr_val PSR;
return ()
od
od"
definition save_retore_sub1 :: "word32 ⇒ word5 ⇒ word5 ⇒ ('a::len,unit) sparc_state_monad"
where "save_retore_sub1 result new_cwp rd ≡
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
new_psr_val ← gets (λs. (update_CWP new_cwp psr_val));
write_cpu new_psr_val PSR;
write_reg result (ucast new_cwp) rd;
return ()
od"
text ‹Operational semantics for SAVE and RESTORE.›
definition save_restore_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "save_restore_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rd = get_operand_w5 (op_list!3)
in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
curr_win ← get_curr_win();
wim_val ← gets (λs. (cpu_reg_val WIM s));
if instr_name = ctrl_type SAVE then
do
new_cwp ← gets (λs. ((word_of_int (((uint curr_win) - 1) mod NWINDOWS)))::word5);
if (get_WIM_bit (unat new_cwp) wim_val) ≠ 0 then
do
raise_trap window_overflow;
return ()
od
else
do
result ← gets (λs. (get_addr op_list s));
save_retore_sub1 result new_cwp rd
od
od
else
do
new_cwp ← gets (λs. ((word_of_int (((uint curr_win) + 1) mod NWINDOWS)))::word5);
if (get_WIM_bit (unat new_cwp) wim_val) ≠ 0 then
do
raise_trap window_underflow;
return ()
od
else
do
result ← gets (λs. (get_addr op_list s));
save_retore_sub1 result new_cwp rd
od
od
od"
definition flush_cache_line :: "word32 ⇒ ('a,unit) sparc_state_monad"
where "flush_cache_line ≡ undefined"
definition flush_Ibuf_and_pipeline :: "word32 ⇒ ('a,unit) sparc_state_monad"
where "flush_Ibuf_and_pipeline ≡ undefined"
text ‹Operational semantics for FLUSH.
Flush the all the caches.›
definition flush_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "flush_instr instr ≡
let op_list = snd instr in
do
addr ← gets (λs. (get_addr op_list s));
modify (λs. (flush_cache_all s));
return ()
od"
text ‹Operational semantics for read state register instructions.
We do not consider RDASR here.›
definition read_state_reg_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "read_state_reg_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!0);
rd = get_operand_w5 (op_list!1)
in
do
curr_win ← get_curr_win();
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
if (instr_name ∈ {sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR} ∨
(instr_name = sreg_type RDASR ∧ privileged_ASR rs1))
∧ ((ucast s_val)::word1) = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if illegal_instruction_ASR rs1 then
do
raise_trap illegal_instruction;
return ()
od
else if rd ≠ 0 then
if instr_name = sreg_type RDY then
do
y_val ← gets (λs. (cpu_reg_val Y s));
write_reg y_val curr_win rd;
return ()
od
else if instr_name = sreg_type RDASR then
do
asr_val ← gets (λs. (cpu_reg_val (ASR rs1) s));
write_reg asr_val curr_win rd;
return ()
od
else if instr_name = sreg_type RDPSR then
do
write_reg psr_val curr_win rd;
return ()
od
else if instr_name = sreg_type RDWIM then
do
wim_val ← gets (λs. (cpu_reg_val WIM s));
write_reg wim_val curr_win rd;
return ()
od
else
do
tbr_val ← gets (λs. (cpu_reg_val TBR s));
write_reg tbr_val curr_win rd;
return ()
od
else return ()
od"
text ‹Operational semantics for write state register instructions.
We do not consider WRASR here.›
definition write_state_reg_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "write_state_reg_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
curr_win ← get_curr_win();
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
op2 ← gets (λs. (get_operand2 op_list s));
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
result ← gets (λs. ((XOR) rs1_val op2));
if instr_name = sreg_type WRY then
do
modify (λs. (delayed_pool_add (DELAYNUM, result, Y) s));
return ()
od
else if instr_name = sreg_type WRASR then
if privileged_ASR rd ∧ s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if illegal_instruction_ASR rd then
do
raise_trap illegal_instruction;
return ()
od
else
do
modify (λs. (delayed_pool_add (DELAYNUM, result, (ASR rd)) s));
return ()
od
else if instr_name = sreg_type WRPSR then
if s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if (uint ((ucast result)::word5)) ≥ NWINDOWS then
do
raise_trap illegal_instruction;
return ()
od
else
do
pil_val ← gets (λs. (get_PIL result));
et_val ← gets (λs. (get_ET result));
new_psr_val ← gets (λs. (update_PSR_et_pil et_val pil_val psr_val));
write_cpu new_psr_val PSR;
modify (λs. (delayed_pool_add (DELAYNUM, result, PSR) s));
return ()
od
else if instr_name = sreg_type WRWIM then
if s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else
do
result_f ← gets (λs. ((result << nat (32 - NWINDOWS)) >> nat (32 - NWINDOWS)));
modify (λs. (delayed_pool_add (DELAYNUM, result_f, WIM) s));
return ()
od
else
if s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else
do
tbr_val ← gets (λs. (cpu_reg_val TBR s));
tbr_val_11_0 ← gets (λs. ((AND) tbr_val 0b00000000000000000000111111111111));
result_tmp ← gets (λs. ((AND) result 0b11111111111111111111000000000000));
result_f ← gets (λs. ((OR) tbr_val_11_0 result_tmp));
modify (λs. (delayed_pool_add (DELAYNUM, result_f, TBR) s));
return ()
od
od"
definition logical_result :: "sparc_operation ⇒ word32 ⇒ word32 ⇒ word32"
where "logical_result instr_name rs1_val operand2 ≡
if (instr_name = logic_type ANDs) ∨
(instr_name = logic_type ANDcc) then
(AND) rs1_val operand2
else if (instr_name = logic_type ANDN) ∨
(instr_name = logic_type ANDNcc) then
(AND) rs1_val (NOT operand2)
else if (instr_name = logic_type ORs) ∨
(instr_name = logic_type ORcc) then
(OR) rs1_val operand2
else if instr_name ∈ {logic_type ORN,logic_type ORNcc} then
(OR) rs1_val (NOT operand2)
else if instr_name ∈ {logic_type XORs,logic_type XORcc} then
(XOR) rs1_val operand2
else
(XOR) rs1_val (NOT operand2)
"
definition logical_new_psr_val :: "word32 ⇒ ('a) sparc_state ⇒ word32"
where "logical_new_psr_val result s ≡
let psr_val = cpu_reg_val PSR s;
n_val = (ucast (result >> 31))::word1;
z_val = if (result = 0) then 1 else 0;
v_val = 0;
c_val = 0
in
update_PSR_icc n_val z_val v_val c_val psr_val
"
definition logical_instr_sub1 :: "sparc_operation ⇒ word32 ⇒
('a::len,unit) sparc_state_monad"
where
"logical_instr_sub1 instr_name result ≡
if instr_name ∈ {logic_type ANDcc,logic_type ANDNcc,logic_type ORcc,
logic_type ORNcc,logic_type XORcc,logic_type XNORcc} then
do
new_psr_val ← gets (λs. (logical_new_psr_val result s));
write_cpu new_psr_val PSR;
return ()
od
else return ()
"
text ‹Operational semantics for logical instructions.›
definition logical_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "logical_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
rd_val ← gets (λs. (user_reg_val curr_win rd s));
result ← gets (λs. (logical_result instr_name rs1_val operand2));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
logical_instr_sub1 instr_name result
od"
text ‹Operational semantics for shift instructions.›
definition shift_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "shift_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
flagi = get_operand_flag (op_list!0);
rs1 = get_operand_w5 (op_list!1);
rs2_shcnt = get_operand_w5 (op_list!2);
rd = get_operand_w5 (op_list!3)
in
do
curr_win ← get_curr_win();
shift_count ← gets (λs. (if flagi = 0 then
ucast (user_reg_val curr_win rs2_shcnt s)
else rs2_shcnt));
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
if (instr_name = shift_type SLL) ∧ (rd ≠ 0) then
do
rd_val ← gets (λs. (rs1_val << (unat shift_count)));
write_reg rd_val curr_win rd;
return ()
od
else if (instr_name = shift_type SRL) ∧ (rd ≠ 0) then
do
rd_val ← gets (λs. (rs1_val >> (unat shift_count)));
write_reg rd_val curr_win rd;
return ()
od
else if (instr_name = shift_type SRA) ∧ (rd ≠ 0) then
do
rd_val ← gets (λs. (rs1_val >>> (unat shift_count)));
write_reg rd_val curr_win rd;
return ()
od
else return ()
od"
definition add_instr_sub1 :: "sparc_operation ⇒ word32 ⇒ word32 ⇒ word32
⇒ ('a::len,unit) sparc_state_monad"
where "add_instr_sub1 instr_name result rs1_val operand2 ≡
if instr_name ∈ {arith_type ADDcc,arith_type ADDXcc} then
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
result_31 ← gets (λs. ((ucast (result >> 31))::word1));
rs1_val_31 ← gets (λs. ((ucast (rs1_val >> 31))::word1));
operand2_31 ← gets (λs. ((ucast (operand2 >> 31))::word1));
new_n_val ← gets (λs. (result_31));
new_z_val ← gets (λs. (if result = 0 then 1::word1 else 0::word1));
new_v_val ← gets (λs. ((OR) ((AND) rs1_val_31
((AND) operand2_31
(NOT result_31)))
((AND) (NOT rs1_val_31)
((AND) (NOT operand2_31)
result_31))));
new_c_val ← gets (λs. ((OR) ((AND) rs1_val_31
operand2_31)
((AND) (NOT result_31)
((OR) rs1_val_31
operand2_31))));
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
return ()
od
else return ()
"
text ‹Operational semantics for add instructions.
These include ADD, ADDcc, ADDX.›
definition add_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "add_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
c_val ← gets (λs. (get_icc_C psr_val));
result ← gets (λs. (if (instr_name = arith_type ADD) ∨
(instr_name = arith_type ADDcc) then
rs1_val + operand2
else
rs1_val + operand2 + (ucast c_val)));
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
add_instr_sub1 instr_name result rs1_val operand2
od"
definition sub_instr_sub1 :: "sparc_operation ⇒ word32 ⇒ word32 ⇒ word32
⇒ ('a::len,unit) sparc_state_monad"
where "sub_instr_sub1 instr_name result rs1_val operand2 ≡
if instr_name ∈ {arith_type SUBcc,arith_type SUBXcc} then
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
result_31 ← gets (λs. ((ucast (result >> 31))::word1));
rs1_val_31 ← gets (λs. ((ucast (rs1_val >> 31))::word1));
operand2_31 ← gets (λs. ((ucast (operand2 >> 31))::word1));
new_n_val ← gets (λs. (result_31));
new_z_val ← gets (λs. (if result = 0 then 1::word1 else 0::word1));
new_v_val ← gets (λs. ((OR) ((AND) rs1_val_31
((AND) (NOT operand2_31)
(NOT result_31)))
((AND) (NOT rs1_val_31)
((AND) operand2_31
result_31))));
new_c_val ← gets (λs. ((OR) ((AND) (NOT rs1_val_31)
operand2_31)
((AND) result_31
((OR) (NOT rs1_val_31)
operand2_31))));
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
return ()
od
else return ()
"
text ‹Operational semantics for subtract instructions.
These include SUB, SUBcc, SUBX.›
definition sub_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "sub_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
c_val ← gets (λs. (get_icc_C psr_val));
result ← gets (λs. (if (instr_name = arith_type SUB) ∨
(instr_name = arith_type SUBcc) then
rs1_val - operand2
else
rs1_val - operand2 - (ucast c_val)));
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
sub_instr_sub1 instr_name result rs1_val operand2
od"
definition mul_instr_sub1 :: "sparc_operation ⇒ word32 ⇒
('a::len,unit) sparc_state_monad"
where "mul_instr_sub1 instr_name result ≡
if instr_name ∈ {arith_type SMULcc,arith_type UMULcc} then
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
new_n_val ← gets (λs. ((ucast (result >> 31))::word1));
new_z_val ← gets (λs. (if result = 0 then 1 else 0));
new_v_val ← gets (λs. 0);
new_c_val ← gets (λs. 0);
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
return ()
od
else return ()
"
text ‹Operational semantics for multiply instructions.›
definition mul_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "mul_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
result0 ← gets (λs. (if instr_name ∈ {arith_type UMUL,arith_type UMULcc} then
(word_of_int ((uint rs1_val) *
(uint operand2)))::word64
else
(word_of_int ((sint rs1_val) *
(sint operand2)))::word64));
y_val ← gets (λs. ((ucast (result0 >> 32))::word32));
write_cpu y_val Y;
result ← gets (λs. ((ucast result0)::word32));
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
mul_instr_sub1 instr_name result
od"
definition div_comp_temp_64bit :: "instruction ⇒ word64 ⇒
virtua_address ⇒ word64"
where "div_comp_temp_64bit i y_rs1 operand2 ≡
if ((fst i) = arith_type UDIV) ∨ ((fst i) = arith_type UDIVcc) then
(word_of_int ((uint y_rs1) div (uint operand2)))::word64
else
let sop1 = sint y_rs1;
sop2 = sint operand2;
pop1 = abs sop1;
pop2 = abs sop2
in
if sop1 > 0 ∧ sop2 > 0 then
(word_of_int (sop1 div sop2))
else if sop1 > 0 ∧ sop2 < 0 then
(word_of_int (- (sop1 div pop2)))
else if sop1 < 0 ∧ sop2 > 0 then
(word_of_int (- (pop1 div sop2)))
else
(word_of_int (pop1 div pop2))"
definition div_comp_temp_V :: "instruction ⇒ word32 ⇒ word33 ⇒ word1"
where "div_comp_temp_V i w32 w33 ≡
if ((fst i) = arith_type UDIV) ∨ ((fst i) = arith_type UDIVcc) then
if w32 = 0 then 0 else 1
else
if (w33 = 0) ∨ (w33 = (0b111111111111111111111111111111111::word33))
then 0 else 1"
definition div_comp_result :: "instruction ⇒ word1 ⇒ word64 ⇒ word32"
where "div_comp_result i temp_V temp_64bit ≡
if temp_V = 1 then
if ((fst i) = arith_type UDIV) ∨ ((fst i) = arith_type UDIVcc) then
(0b11111111111111111111111111111111::word32)
else if (fst i) ∈ {arith_type SDIV,arith_type SDIVcc} then
if temp_64bit > 0 then
(0b01111111111111111111111111111111::word32)
else ((word_of_int (0 - (uint (0b10000000000000000000000000000000::word32))))::word32)
else ((ucast temp_64bit)::word32)
else ((ucast temp_64bit)::word32)"
definition div_write_new_val :: "instruction ⇒ word32 ⇒ word1 ⇒
('a::len,unit) sparc_state_monad"
where "div_write_new_val i result temp_V ≡
if (fst i) ∈ {arith_type UDIVcc,arith_type SDIVcc} then
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
new_n_val ← gets (λs. ((ucast (result >> 31))::word1));
new_z_val ← gets (λs. (if result = 0 then 1 else 0));
new_v_val ← gets (λs. temp_V);
new_c_val ← gets (λs. 0);
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
return ()
od
else return ()"
definition div_comp :: "instruction ⇒ word5 ⇒ word5 ⇒ virtua_address ⇒
('a::len,unit) sparc_state_monad"
where "div_comp instr rs1 rd operand2 ≡
do
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
y_val ← gets (λs. (cpu_reg_val Y s));
y_rs1 ← gets (λs. ((word_cat y_val rs1_val)::word64));
temp_64bit ← gets (λs. (div_comp_temp_64bit instr y_rs1 operand2));
temp_high32 ← gets (λs. ((ucast (temp_64bit >> 32))::word32));
temp_high33 ← gets (λs. ((ucast (temp_64bit >> 31))::word33));
temp_V ← gets (λs. (div_comp_temp_V instr temp_high32 temp_high33));
result ← gets (λs. (div_comp_result instr temp_V temp_64bit));
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
div_write_new_val instr result temp_V
od"
text ‹Operational semantics for divide instructions.›
definition div_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "div_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
if (uint operand2) = 0 then
do
raise_trap division_by_zero;
return ()
od
else
div_comp instr rs1 rd operand2
od"
definition ld_word0 :: "instruction ⇒ word32 ⇒ virtua_address ⇒ word32"
where "ld_word0 instr data_word address ≡
if (fst instr) ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDSBA} then
let byte = if (uint ((ucast address)::word2)) = 0 then
(ucast (data_word >> 24))::word8
else if (uint ((ucast address)::word2)) = 1 then
(ucast (data_word >> 16))::word8
else if (uint ((ucast address)::word2)) = 2 then
(ucast (data_word >> 8))::word8
else
(ucast data_word)::word8
in
if (fst instr) = load_store_type LDSB ∨ (fst instr) = load_store_type LDSBA then
sign_ext8 byte
else
zero_ext8 byte
else if (fst instr) = load_store_type LDUH ∨ (fst instr) = load_store_type LDSH ∨
(fst instr) = load_store_type LDSHA ∨ (fst instr) = load_store_type LDUHA
then
let halfword = if (uint ((ucast address)::word2)) = 0 then
(ucast (data_word >> 16))::word16
else
(ucast data_word)::word16
in
if (fst instr) = load_store_type LDSH ∨ (fst instr) = load_store_type LDSHA then
sign_ext16 halfword
else
zero_ext16 halfword
else
data_word
"
definition ld_asi :: "instruction ⇒ word1 ⇒ asi_type"
where "ld_asi instr s_val ≡
if (fst instr) ∈ {load_store_type LDD,load_store_type LD,load_store_type LDUH,
load_store_type LDSB,load_store_type LDUB,load_store_type LDSH} then
if s_val = 0 then (word_of_int 10)::asi_type
else (word_of_int 11)::asi_type
else
get_operand_asi ((snd instr)!3)
"
definition load_sub2 :: "virtua_address ⇒ asi_type ⇒ word5 ⇒
('a::len) window_size ⇒ word32 ⇒ ('a,unit) sparc_state_monad"
where "load_sub2 address asi rd curr_win word0 ≡
do
write_reg word0 curr_win ((AND) rd 0b11110);
(result1,new_state1) ← gets (λs. (memory_read asi (address + 4) s));
if result1 = None then
do
raise_trap data_access_exception;
return ()
od
else
do
word1 ← gets (λs. (case result1 of Some v ⇒ v));
modify (λs. (new_state1));
write_reg word1 curr_win ((OR) rd 1);
return ()
od
od"
definition load_sub3 :: "instruction ⇒ ('a::len) window_size ⇒
word5 ⇒ asi_type ⇒ virtua_address ⇒
('a::len,unit) sparc_state_monad"
where "load_sub3 instr curr_win rd asi address ≡
do
(result,new_state) ← gets (λs. (memory_read asi address s));
if result = None then
do
raise_trap data_access_exception;
return ()
od
else
do
data_word ← gets (λs. (case result of Some v ⇒ v));
modify (λs. (new_state));
word0 ← gets (λs. (ld_word0 instr data_word address));
if rd ≠ 0 ∧ (fst instr) ∈ {load_store_type LD,load_store_type LDA,
load_store_type LDUH,load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDSH,load_store_type LDSHA,
load_store_type LDUHA,load_store_type LDSBA} then
do
write_reg word0 curr_win rd;
return ()
od
else
load_sub2 address asi rd curr_win word0
od
od"
definition load_sub1 :: "instruction ⇒ word5 ⇒ word1 ⇒
('a::len,unit) sparc_state_monad"
where "load_sub1 instr rd s_val ≡
do
curr_win ← get_curr_win();
address ← gets (λs. (get_addr (snd instr) s));
asi ← gets (λs. (ld_asi instr s_val));
if (((fst instr) = load_store_type LDD ∨ (fst instr) = load_store_type LDDA)
∧ ((ucast address)::word3) ≠ 0)
∨ ((fst instr) ∈ {load_store_type LD,load_store_type LDA}
∧ ((ucast address)::word2) ≠ 0)
∨ (((fst instr) = load_store_type LDUH ∨ (fst instr) = load_store_type LDUHA
∨ (fst instr) = load_store_type LDSH ∨ (fst instr) = load_store_type LDSHA)
∧ ((ucast address)::word1) ≠ 0)
then
do
raise_trap mem_address_not_aligned;
return ()
od
else
load_sub3 instr curr_win rd asi address
od"
text ‹Operational semantics for Load instructions.›
definition load_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "load_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
flagi = get_operand_flag (op_list!0);
rd = if instr_name ∈ {load_store_type LDUBA,load_store_type LDA,
load_store_type LDSBA,load_store_type LDSHA,
load_store_type LDSHA,load_store_type LDDA} then
get_operand_w5 (op_list!4)
else
get_operand_w5 (op_list!3)
in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
if instr_name ∈ {load_store_type LDA,load_store_type LDUBA,
load_store_type LDSBA,load_store_type LDSHA,
load_store_type LDUHA,load_store_type LDDA} ∧ s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if instr_name ∈ {load_store_type LDA,load_store_type LDUBA,
load_store_type LDSBA,load_store_type LDSHA,load_store_type LDUHA,
load_store_type LDDA} ∧ flagi = 1 then
do
raise_trap illegal_instruction;
return ()
od
else
load_sub1 instr rd s_val
od"
definition st_asi :: "instruction ⇒ word1 ⇒ asi_type"
where "st_asi instr s_val ≡
if (fst instr) ∈ {load_store_type STD,load_store_type ST,
load_store_type STH,load_store_type STB} then
if s_val = 0 then (word_of_int 10)::asi_type
else (word_of_int 11)::asi_type
else
get_operand_asi ((snd instr)!3)
"
definition st_byte_mask :: "instruction ⇒ virtua_address ⇒ word4"
where "st_byte_mask instr address ≡
if (fst instr) ∈ {load_store_type STD,load_store_type ST,
load_store_type STA,load_store_type STDA} then
(0b1111::word4)
else if (fst instr) ∈ {load_store_type STH,load_store_type STHA} then
if ((ucast address)::word2) = 0 then
(0b1100::word4)
else
(0b0011::word4)
else
if ((ucast address)::word2) = 0 then
(0b1000::word4)
else if ((ucast address)::word2) = 1 then
(0b0100::word4)
else if ((ucast address)::word2) = 2 then
(0b0010::word4)
else
(0b0001::word4)
"
definition st_data0 :: "instruction ⇒ ('a::len) window_size ⇒
word5 ⇒ virtua_address ⇒ ('a) sparc_state ⇒ reg_type"
where "st_data0 instr curr_win rd address s ≡
if (fst instr) ∈ {load_store_type STD,load_store_type STDA} then
user_reg_val curr_win ((AND) rd 0b11110) s
else if (fst instr) ∈ {load_store_type ST,load_store_type STA} then
user_reg_val curr_win rd s
else if (fst instr) ∈ {load_store_type STH,load_store_type STHA} then
if ((ucast address)::word2) = 0 then
(user_reg_val curr_win rd s) << 16
else
user_reg_val curr_win rd s
else
if ((ucast address)::word2) = 0 then
(user_reg_val curr_win rd s) << 24
else if ((ucast address)::word2) = 1 then
(user_reg_val curr_win rd s) << 16
else if ((ucast address)::word2) = 2 then
(user_reg_val curr_win rd s) << 8
else
user_reg_val curr_win rd s
"
definition store_sub2 :: "instruction ⇒ ('a::len) window_size ⇒
word5 ⇒ asi_type ⇒ virtua_address ⇒
('a::len,unit) sparc_state_monad"
where "store_sub2 instr curr_win rd asi address ≡
do
byte_mask ← gets (λs. (st_byte_mask instr address));
data0 ← gets (λs. (st_data0 instr curr_win rd address s));
result0 ← gets (λs. (memory_write asi address byte_mask data0 s));
if result0 = None then
do
raise_trap data_access_exception;
return ()
od
else
do
new_state ← gets (λs. (case result0 of Some v ⇒ v));
modify (λs. (new_state));
if (fst instr) ∈ {load_store_type STD,load_store_type STDA} then
do
data1 ← gets (λs. (user_reg_val curr_win ((OR) rd 0b00001) s));
result1 ← gets (λs. (memory_write asi (address + 4) (0b1111::word4) data1 s));
if result1 = None then
do
raise_trap data_access_exception;
return ()
od
else
do
new_state1 ← gets (λs. (case result1 of Some v ⇒ v));
modify (λs. (new_state1));
return ()
od
od
else
return ()
od
od"
definition store_sub1 :: "instruction ⇒ word5 ⇒ word1 ⇒
('a::len,unit) sparc_state_monad"
where "store_sub1 instr rd s_val ≡
do
curr_win ← get_curr_win();
address ← gets (λs. (get_addr (snd instr) s));
asi ← gets (λs. (st_asi instr s_val));
if ((fst instr) = load_store_type STH ∨ (fst instr) = load_store_type STHA)
∧ ((ucast address)::word1) ≠ 0 then
do
raise_trap mem_address_not_aligned;
return ()
od
else if (fst instr) ∈ {load_store_type ST,load_store_type STA}
∧ ((ucast address)::word2) ≠ 0 then
do
raise_trap mem_address_not_aligned;
return ()
od
else if (fst instr) ∈ {load_store_type STD,load_store_type STDA}
∧ ((ucast address)::word3) ≠ 0 then
do
raise_trap mem_address_not_aligned;
return ()
od
else
store_sub2 instr curr_win rd asi address
od"
text ‹Operational semantics for Store instructions.›
definition store_instr :: "instruction ⇒
('a::len,unit) sparc_state_monad"
where "store_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
flagi = get_operand_flag (op_list!0);
rd = if instr_name ∈ {load_store_type STA,load_store_type STBA,
load_store_type STHA,load_store_type STDA} then
get_operand_w5 (op_list!4)
else
get_operand_w5 (op_list!3)
in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
if instr_name ∈ {load_store_type STA,load_store_type STDA,
load_store_type STHA,load_store_type STBA} ∧ s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if instr_name ∈ {load_store_type STA,load_store_type STDA,
load_store_type STHA,load_store_type STBA} ∧ flagi = 1 then
do
raise_trap illegal_instruction;
return ()
od
else
store_sub1 instr rd s_val
od"
text ‹The instructions below are not used by Xtratum and they are
not tested.›
definition ldst_asi :: "instruction ⇒ word1 ⇒ asi_type"
where "ldst_asi instr s_val ≡
if (fst instr) ∈ {load_store_type LDSTUB} then
if s_val = 0 then (word_of_int 10)::asi_type
else (word_of_int 11)::asi_type
else
get_operand_asi ((snd instr)!3)
"
definition ldst_word0 :: "instruction ⇒ word32 ⇒ virtua_address ⇒ word32"
where "ldst_word0 instr data_word address ≡
let byte = if (uint ((ucast address)::word2)) = 0 then
(ucast (data_word >> 24))::word8
else if (uint ((ucast address)::word2)) = 1 then
(ucast (data_word >> 16))::word8
else if (uint ((ucast address)::word2)) = 2 then
(ucast (data_word >> 8))::word8
else
(ucast data_word)::word8
in
zero_ext8 byte
"
definition ldst_byte_mask :: "instruction ⇒ virtua_address ⇒ word4"
where "ldst_byte_mask instr address ≡
if ((ucast address)::word2) = 0 then
(0b1000::word4)
else if ((ucast address)::word2) = 1 then
(0b0100::word4)
else if ((ucast address)::word2) = 2 then
(0b0010::word4)
else
(0b0001::word4)
"
definition load_store_sub1 :: "instruction ⇒ word5 ⇒ word1 ⇒
('a::len,unit) sparc_state_monad"
where "load_store_sub1 instr rd s_val ≡
do
curr_win ← get_curr_win();
address ← gets (λs. (get_addr (snd instr) s));
asi ← gets (λs. (ldst_asi instr s_val));
block_byte ← gets (λs. (pb_block_ldst_byte_val address s));
block_word ← gets (λs. (pb_block_ldst_word_val address s));
if block_byte ∨ block_word then
do
pc_val ← gets (λs. (cpu_reg_val PC s));
write_cpu pc_val nPC;
return ()
od
else
do
modify (λs. (pb_block_ldst_byte_mod address True s));
(result,new_state) ← gets (λs. (memory_read asi address s));
if result = None then
do
raise_trap data_access_exception;
return ()
od
else
do
data_word ← gets (λs. (case result of Some v ⇒ v));
modify (λs. (new_state));
byte_mask ← gets (λs. (ldst_byte_mask instr address));
data0 ← gets (λs. (0b11111111111111111111111111111111::word32));
result0 ← gets (λs. (memory_write asi address byte_mask data0 s));
modify (λs. (pb_block_ldst_byte_mod address False s));
if result0 = None then
do
raise_trap data_access_exception;
return ()
od
else
do
new_state1 ← gets (λs. (case result0 of Some v ⇒ v));
modify (λs. (new_state1));
word0 ← gets (λs. (ldst_word0 instr data_word address));
if rd ≠ 0 then
do
write_reg word0 curr_win rd;
return ()
od
else
return ()
od
od
od
od"
text ‹Operational semantics for atomic load-store.›
definition load_store_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "load_store_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
flagi = get_operand_flag (op_list!0);
rd = if instr_name ∈ {load_store_type LDSTUBA} then
get_operand_w5 (op_list!4)
else
get_operand_w5 (op_list!3)
in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
if instr_name ∈ {load_store_type LDSTUBA} ∧ s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if instr_name ∈ {load_store_type LDSTUBA} ∧ flagi = 1 then
do
raise_trap illegal_instruction;
return ()
od
else
load_store_sub1 instr rd s_val
od"
definition swap_sub1 :: "instruction ⇒ word5 ⇒ word1 ⇒
('a::len,unit) sparc_state_monad"
where "swap_sub1 instr rd s_val ≡
do
curr_win ← get_curr_win();
address ← gets (λs. (get_addr (snd instr) s));
asi ← gets (λs. (ldst_asi instr s_val));
temp ← gets (λs. (user_reg_val curr_win rd s));
block_byte ← gets (λs. (pb_block_ldst_byte_val address s));
block_word ← gets (λs. (pb_block_ldst_word_val address s));
if block_byte ∨ block_word then
do
pc_val ← gets (λs. (cpu_reg_val PC s));
write_cpu pc_val nPC;
return ()
od
else
do
modify (λs. (pb_block_ldst_word_mod address True s));
(result,new_state) ← gets (λs. (memory_read asi address s));
if result = None then
do
raise_trap data_access_exception;
return ()
od
else
do
word ← gets (λs. (case result of Some v ⇒ v));
modify (λs. (new_state));
byte_mask ← gets (λs. (0b1111::word4));
result0 ← gets (λs. (memory_write asi address byte_mask temp s));
modify (λs. (pb_block_ldst_word_mod address False s));
if result0 = None then
do
raise_trap data_access_exception;
return ()
od
else
do
new_state1 ← gets (λs. (case result0 of Some v ⇒ v));
modify (λs. (new_state1));
if rd ≠ 0 then
do
write_reg word curr_win rd;
return ()
od
else
return ()
od
od
od
od"
text ‹Operational semantics for swap.›
definition swap_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "swap_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
flagi = get_operand_flag (op_list!0);
rd = if instr_name ∈ {load_store_type SWAPA} then
get_operand_w5 (op_list!4)
else
get_operand_w5 (op_list!3)
in
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. (get_S psr_val));
if instr_name ∈ {load_store_type SWAPA} ∧ s_val = 0 then
do
raise_trap privileged_instruction;
return ()
od
else if instr_name ∈ {load_store_type SWAPA} ∧ flagi = 1 then
do
raise_trap illegal_instruction;
return ()
od
else
swap_sub1 instr rd s_val
od"
definition bit2_zero :: "word2 ⇒ word1"
where "bit2_zero w2 ≡ if w2 ≠ 0 then 1 else 0"
text ‹Operational semantics for tagged add instructions.›
definition tadd_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "tadd_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
c_val ← gets (λs. (get_icc_C psr_val));
result ← gets (λs. (rs1_val + operand2));
result_31 ← gets (λs. ((ucast (result >> 31))::word1));
rs1_val_31 ← gets (λs. ((ucast (rs1_val >> 31))::word1));
operand2_31 ← gets (λs. ((ucast (operand2 >> 31))::word1));
rs1_val_2 ← gets (λs. (bit2_zero ((ucast rs1_val)::word2)));
operand2_2 ← gets (λs. (bit2_zero ((ucast operand2)::word2)));
temp_V ← gets (λs. ((OR) ((OR) ((AND) rs1_val_31
((AND) operand2_31
(NOT result_31)))
((AND) (NOT rs1_val_31)
((AND) (NOT operand2_31)
result_31)))
((OR) rs1_val_2 operand2_2)));
if instr_name = arith_type TADDccTV ∧ temp_V = 1 then
do
raise_trap tag_overflow;
return ()
od
else
do
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
new_n_val ← gets (λs. (result_31));
new_z_val ← gets (λs. (if result = 0 then 1::word1 else 0::word1));
new_v_val ← gets (λs. temp_V);
new_c_val ← gets (λs. ((OR) ((AND) rs1_val_31
operand2_31)
((AND) (NOT result_31)
((OR) rs1_val_31
operand2_31))));
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
return ()
od
od"
text ‹Operational semantics for tagged add instructions.›
definition tsub_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "tsub_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
operand2 ← gets (λs. (get_operand2 op_list s));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
c_val ← gets (λs. (get_icc_C psr_val));
result ← gets (λs. (rs1_val - operand2));
result_31 ← gets (λs. ((ucast (result >> 31))::word1));
rs1_val_31 ← gets (λs. ((ucast (rs1_val >> 31))::word1));
operand2_31 ← gets (λs. ((ucast (operand2 >> 31))::word1));
rs1_val_2 ← gets (λs. (bit2_zero ((ucast rs1_val)::word2)));
operand2_2 ← gets (λs. (bit2_zero ((ucast operand2)::word2)));
temp_V ← gets (λs. ((OR) ((OR) ((AND) rs1_val_31
((AND) operand2_31
(NOT result_31)))
((AND) (NOT rs1_val_31)
((AND) (NOT operand2_31)
result_31)))
((OR) rs1_val_2 operand2_2)));
if instr_name = arith_type TSUBccTV ∧ temp_V = 1 then
do
raise_trap tag_overflow;
return ()
od
else
do
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
new_n_val ← gets (λs. (result_31));
new_z_val ← gets (λs. (if result = 0 then 1::word1 else 0::word1));
new_v_val ← gets (λs. temp_V);
new_c_val ← gets (λs. ((OR) ((AND) rs1_val_31
operand2_31)
((AND) (NOT result_31)
((OR) rs1_val_31
operand2_31))));
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
return ()
od
od"
definition muls_op2 :: "inst_operand list ⇒ ('a::len) sparc_state ⇒ word32"
where "muls_op2 op_list s ≡
let y_val = cpu_reg_val Y s in
if ((ucast y_val)::word1) = 0 then 0
else get_operand2 op_list s
"
text ‹Operational semantics for multiply step instruction.›
definition muls_instr :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "muls_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1);
rd = get_operand_w5 (op_list!3)
in
do
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
n_val ← gets (λs. (get_icc_N psr_val));
v_val ← gets (λs. (get_icc_V psr_val));
c_val ← gets (λs. (get_icc_C psr_val));
y_val ← gets (λs. (cpu_reg_val Y s));
operand1 ← gets (λs. (word_cat ((XOR) n_val v_val)
((ucast (rs1_val >> 1))::word31)));
operand2 ← gets (λs. (muls_op2 op_list s));
result ← gets (λs. (operand1 + operand2));
new_y_val ← gets (λs. (word_cat ((ucast rs1_val)::word1) ((ucast (y_val >> 1))::word31)));
write_cpu new_y_val Y;
rd_val ← gets (λs. (user_reg_val curr_win rd s));
new_rd_val ← gets (λs. (if rd ≠ 0 then result else rd_val));
write_reg new_rd_val curr_win rd;
result_31 ← gets (λs. ((ucast (result >> 31))::word1));
operand1_31 ← gets (λs. ((ucast (operand1 >> 31))::word1));
operand2_31 ← gets (λs. ((ucast (operand2 >> 31))::word1));
new_n_val ← gets (λs. (result_31));
new_z_val ← gets (λs. (if result = 0 then 1::word1 else 0::word1));
new_v_val ← gets (λs. ((OR) ((AND) operand1_31
((AND) operand2_31
(NOT result_31)))
((AND) (NOT operand1_31)
((AND) (NOT operand2_31)
result_31))));
new_c_val ← gets (λs. ((OR) ((AND) operand1_31
operand2_31)
((AND) (NOT result_31)
((OR) operand1_31
operand2_31))));
new_psr_val ← gets (λs. (update_PSR_icc new_n_val
new_z_val
new_v_val
new_c_val psr_val));
write_cpu new_psr_val PSR;
return ()
od"
text‹Evaluate icc based on the bits N, Z, V, C in PSR
and the type of ticc instruction.
See Sparcv8 manual Page 182.›
definition trap_eval_icc::"sparc_operation ⇒ word1 ⇒ word1 ⇒ word1 ⇒ word1 ⇒ int"
where "trap_eval_icc instr_name n_val z_val v_val c_val ≡
if instr_name = ticc_type TNE then
if z_val = 0 then 1 else 0
else if instr_name = ticc_type TE then
if z_val = 1 then 1 else 0
else if instr_name = ticc_type TG then
if ((OR) z_val (n_val XOR v_val)) = 0 then 1 else 0
else if instr_name = ticc_type TLE then
if ((OR) z_val (n_val XOR v_val)) = 1 then 1 else 0
else if instr_name = ticc_type TGE then
if (n_val XOR v_val) = 0 then 1 else 0
else if instr_name = ticc_type TL then
if (n_val XOR v_val) = 1 then 1 else 0
else if instr_name = ticc_type TGU then
if (c_val = 0 ∧ z_val = 0) then 1 else 0
else if instr_name = ticc_type TLEU then
if (c_val = 1 ∨ z_val = 1) then 1 else 0
else if instr_name = ticc_type TCC then
if c_val = 0 then 1 else 0
else if instr_name = ticc_type TCS then
if c_val = 1 then 1 else 0
else if instr_name = ticc_type TPOS then
if n_val = 0 then 1 else 0
else if instr_name = ticc_type TNEG then
if n_val = 1 then 1 else 0
else if instr_name = ticc_type TVC then
if v_val = 0 then 1 else 0
else if instr_name = ticc_type TVS then
if v_val = 1 then 1 else 0
else if instr_name = ticc_type TA then 1
else if instr_name = ticc_type TN then 0
else -1
"
text ‹
Get ‹operand2› for ‹ticc› based on the flag ‹i›, ‹rs1›, ‹rs2›, and ‹trap_imm7›.
If ‹i = 0› then ‹operand2 = r[rs2]›,
else ‹operand2 = sign_ext7(trap_imm7)›.
‹op_list› should be ‹[i,rs1,rs2]› or ‹[i,rs1,trap_imm7]›.
›
definition get_trap_op2::"inst_operand list ⇒ ('a::len) sparc_state
⇒ virtua_address"
where "get_trap_op2 op_list s ≡
let flagi = get_operand_flag (op_list!0);
curr_win = ucast (get_CWP (cpu_reg_val PSR s))
in
if flagi = 0 then
let rs2 = get_operand_w5 (op_list!2);
rs2_val = user_reg_val curr_win rs2 s
in rs2_val
else
let ext_simm7 = sign_ext7 (get_operand_imm7 (op_list!2)) in
ext_simm7
"
text ‹Operational semantics for Ticc insturctions.›
definition ticc_instr::"instruction ⇒
('a::len,unit) sparc_state_monad"
where "ticc_instr instr ≡
let instr_name = fst instr;
op_list = snd instr;
rs1 = get_operand_w5 (op_list!1)
in
do
n_val ← gets (λs. get_icc_N ((cpu_reg s) PSR));
z_val ← gets (λs. get_icc_Z ((cpu_reg s) PSR));
v_val ← gets (λs. get_icc_V ((cpu_reg s) PSR));
c_val ← gets (λs. get_icc_C ((cpu_reg s) PSR));
icc_val ← gets(λs. (trap_eval_icc instr_name n_val z_val v_val c_val));
curr_win ← get_curr_win();
rs1_val ← gets (λs. (user_reg_val curr_win rs1 s));
trap_number ← gets (λs. (rs1_val + (get_trap_op2 op_list s)));
npc_val ← gets (λs. (cpu_reg_val nPC s));
pc_val ← gets (λs. (cpu_reg_val PC s));
if icc_val = 1 then
do
raise_trap trap_instruction;
trap_number7 ← gets (λs. ((ucast trap_number)::word7));
modify (λs. (ticc_trap_type_mod trap_number7 s));
return ()
od
else
do
write_cpu npc_val PC;
write_cpu (npc_val + 4) nPC;
return ()
od
od"
text ‹Operational semantics for store barrier.›
definition store_barrier_instr::"instruction ⇒ ('a::len,unit) sparc_state_monad"
where "store_barrier_instr instr ≡
do
modify (λs. (store_barrier_pending_mod True s));
return ()
od"
end
Theory Sparc_Execution
theory Sparc_Execution
imports Main Sparc_Instruction Sparc_State Sparc_Types
"HOL-Eisbach.Eisbach_Tools"
begin
primrec sum :: "nat ⇒ nat" where
"sum 0 = 0" |
"sum (Suc n) = Suc n + sum n"
definition select_trap :: "unit ⇒ ('a,unit) sparc_state_monad"
where "select_trap _ ≡
do
traps ← gets (λs. (get_trap_set s));
rt_val ← gets (λs. (reset_trap_val s));
psr_val ← gets (λs. (cpu_reg_val PSR s));
et_val ← gets (λs. (get_ET psr_val));
modify (λs. (emp_trap_set s));
if rt_val = True then
return ()
else if et_val = 0 then
do
set_err_mode True;
set_exe_mode False;
fail ()
od
else if data_store_error ∈ traps then
do
write_cpu_tt (0b00101011::word8);
return ()
od
else if instruction_access_error ∈ traps then
do
write_cpu_tt (0b00100001::word8);
return ()
od
else if r_register_access_error ∈ traps then
do
write_cpu_tt (0b00100000::word8);
return ()
od
else if instruction_access_exception ∈ traps then
do
write_cpu_tt (0b00000001::word8);
return ()
od
else if privileged_instruction ∈ traps then
do
write_cpu_tt (0b00000011::word8);
return ()
od
else if illegal_instruction ∈ traps then
do
write_cpu_tt (0b00000010::word8);
return ()
od
else if fp_disabled ∈ traps then
do
write_cpu_tt (0b00000100::word8);
return ()
od
else if cp_disabled ∈ traps then
do
write_cpu_tt (0b00100100::word8);
return ()
od
else if unimplemented_FLUSH ∈ traps then
do
write_cpu_tt (0b00100101::word8);
return ()
od
else if window_overflow ∈ traps then
do
write_cpu_tt (0b00000101::word8);
return ()
od
else if window_underflow ∈ traps then
do
write_cpu_tt (0b00000110::word8);
return ()
od
else if mem_address_not_aligned ∈ traps then
do
write_cpu_tt (0b00000111::word8);
return ()
od
else if fp_exception ∈ traps then
do
write_cpu_tt (0b00001000::word8);
return ()
od
else if cp_exception ∈ traps then
do
write_cpu_tt (0b00101000::word8);
return ()
od
else if data_access_error ∈ traps then
do
write_cpu_tt (0b00101001::word8);
return ()
od
else if data_access_exception ∈ traps then
do
write_cpu_tt (0b00001001::word8);
return ()
od
else if tag_overflow ∈ traps then
do
write_cpu_tt (0b00001010::word8);
return ()
od
else if division_by_zero ∈ traps then
do
write_cpu_tt (0b00101010::word8);
return ()
od
else if trap_instruction ∈ traps then
do
ticc_trap_type ← gets (λs. (ticc_trap_type_val s));
write_cpu_tt (word_cat (1::word1) ticc_trap_type);
return ()
od
else return ()
od"
definition exe_trap_st_pc :: "unit ⇒ ('a::len,unit) sparc_state_monad"
where "exe_trap_st_pc _ ≡
do
annul ← gets (λs. (annul_val s));
pc_val ← gets (λs. (cpu_reg_val PC s));
npc_val ← gets (λs. (cpu_reg_val nPC s));
curr_win ← get_curr_win();
if annul = False then
do
write_reg pc_val curr_win (word_of_int 17);
write_reg npc_val curr_win (word_of_int 18);
return ()
od
else
do
write_reg npc_val curr_win (word_of_int 17);
write_reg (npc_val + 4) curr_win (word_of_int 18);
set_annul False;
return ()
od
od"
definition exe_trap_wr_pc :: "unit ⇒ ('a::len,unit) sparc_state_monad"
where "exe_trap_wr_pc _ ≡
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
new_psr_val ← gets (λs. (update_S (1::word1) psr_val));
write_cpu new_psr_val PSR;
reset_trap ← gets (λs. (reset_trap_val s));
tbr_val ← gets (λs. (cpu_reg_val TBR s));
if reset_trap = False then
do
write_cpu tbr_val PC;
write_cpu (tbr_val + 4) nPC;
return ()
od
else
do
write_cpu 0 PC;
write_cpu 4 nPC;
set_reset_trap False;
return ()
od
od"
definition execute_trap :: "unit ⇒ ('a::len,unit) sparc_state_monad"
where "execute_trap _ ≡
do
select_trap();
err_mode ← gets (λs. (err_mode_val s));
if err_mode = True then
return ()
else
do
psr_val ← gets (λs. (cpu_reg_val PSR s));
s_val ← gets (λs. ((ucast (get_S psr_val))::word1));
curr_win ← get_curr_win();
new_cwp ← gets (λs. ((word_of_int (((uint curr_win) - 1) mod NWINDOWS)))::word5);
new_psr_val ← gets (λs. (update_PSR_exe_trap new_cwp (0::word1) s_val psr_val));
write_cpu new_psr_val PSR;
exe_trap_st_pc();
exe_trap_wr_pc();
return ()
od
od"
definition dispatch_instruction :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "dispatch_instruction instr ≡
let instr_name = fst instr in
do
traps ← gets (λs. (get_trap_set s));
if traps = {} then
if instr_name ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD} then
load_instr instr
else if instr_name ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD} then
store_instr instr
else if instr_name ∈ {sethi_type SETHI} then
sethi_instr instr
else if instr_name ∈ {nop_type NOP} then
nop_instr instr
else if instr_name ∈ {logic_type ANDs,logic_type ANDcc,logic_type ANDN,
logic_type ANDNcc,logic_type ORs,logic_type ORcc,logic_type ORN,
logic_type XORs,logic_type XNOR} then
logical_instr instr
else if instr_name ∈ {shift_type SLL,shift_type SRL,shift_type SRA} then
shift_instr instr
else if instr_name ∈ {arith_type ADD,arith_type ADDcc,arith_type ADDX} then
add_instr instr
else if instr_name ∈ {arith_type SUB,arith_type SUBcc,arith_type SUBX} then
sub_instr instr
else if instr_name ∈ {arith_type UMUL,arith_type SMUL,arith_type SMULcc} then
mul_instr instr
else if instr_name ∈ {arith_type UDIV,arith_type UDIVcc,arith_type SDIV} then
div_instr instr
else if instr_name ∈ {ctrl_type SAVE,ctrl_type RESTORE} then
save_restore_instr instr
else if instr_name ∈ {call_type CALL} then
call_instr instr
else if instr_name ∈ {ctrl_type JMPL} then
jmpl_instr instr
else if instr_name ∈ {ctrl_type RETT} then
rett_instr instr
else if instr_name ∈ {sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,
sreg_type RDTBR} then
read_state_reg_instr instr
else if instr_name ∈ {sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,
sreg_type WRTBR} then
write_state_reg_instr instr
else if instr_name ∈ {load_store_type FLUSH} then
flush_instr instr
else if instr_name ∈ {bicc_type BE,bicc_type BNE,bicc_type BGU,
bicc_type BLE,bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,bicc_type BN} then
branch_instr instr
else fail ()
else return ()
od"
definition supported_instruction :: "sparc_operation ⇒ bool"
where "supported_instruction instr ≡
if instr ∈ {load_store_type LDSB,load_store_type LDUB,load_store_type LDUBA,
load_store_type LDUH,load_store_type LD,load_store_type LDA,
load_store_type LDD,
load_store_type STB,load_store_type STH,load_store_type ST,
load_store_type STA,load_store_type STD,
sethi_type SETHI,
nop_type NOP,
logic_type ANDs,logic_type ANDcc,logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
ctrl_type RETT,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}
then True
else False
"
definition execute_instr_sub1 :: "instruction ⇒ ('a::len,unit) sparc_state_monad"
where "execute_instr_sub1 instr ≡
do
instr_name ← gets (λs. (fst instr));
traps2 ← gets (λs. (get_trap_set s));
if traps2 = {} ∧ instr_name ∉ {call_type CALL,ctrl_type RETT,ctrl_type JMPL,
bicc_type BE,bicc_type BNE,bicc_type BGU,
bicc_type BLE,bicc_type BL,bicc_type BGE,
bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,
bicc_type BA,bicc_type BN} then
do
npc_val ← gets (λs. (cpu_reg_val nPC s));
write_cpu npc_val PC;
write_cpu (npc_val + 4) nPC;
return ()
od
else return ()
od"
definition execute_instruction :: "unit ⇒ ('a::len,unit) sparc_state_monad"
where "execute_instruction _ ≡
do
traps ← gets (λs. (get_trap_set s));
if traps = {} then
do
exe_mode ← gets (λs. (exe_mode_val s));
if exe_mode = True then
do
modify (λs. (delayed_pool_write s));
fetch_result ← gets (λs. (fetch_instruction s));
case fetch_result of
Inl e1 ⇒ (do
raise_trap instruction_access_exception;
return ()
od)
| Inr v1 ⇒ (do
dec ← gets (λs. (decode_instruction v1));
case dec of
Inl e2 ⇒ (
fail ()
)
| Inr v2 ⇒ (do
instr ← gets (λs. (v2));
annul ← gets (λs. (annul_val s));
if annul = False then
do
dispatch_instruction instr;
execute_instr_sub1 instr;
return ()
od
else
do
set_annul False;
npc_val ← gets (λs. (cpu_reg_val nPC s));
write_cpu npc_val PC;
write_cpu (npc_val + 4) nPC;
return ()
od
od)
od)
od
else return ()
od
else
do
execute_trap();
return ()
od
od"
definition NEXT :: "('a::len)sparc_state ⇒ ('a)sparc_state option"
where "NEXT s ≡ case execute_instruction () s of (_,True) ⇒ None
| (s',False) ⇒ Some (snd s')"
definition good_context :: "('a::len) sparc_state ⇒ bool"
where "good_context s ≡
let traps = get_trap_set s;
psr_val = cpu_reg_val PSR s;
et_val = get_ET psr_val;
rt_val = reset_trap_val s
in
if traps ≠ {} ∧ rt_val = False ∧ et_val = 0 then False
else
let s' = delayed_pool_write s in
case fetch_instruction s' of
Inl _ ⇒ True
|Inr v ⇒ (
case decode_instruction v of
Inl _ ⇒ False
|Inr instr ⇒ (
let annul = annul_val s' in
if annul = True then True
else
if supported_instruction (fst instr) then
if (fst instr) = ctrl_type RETT then
let curr_win_r = (get_CWP (cpu_reg_val PSR s'));
new_cwp_int_r = (((uint curr_win_r) + 1) mod NWINDOWS);
wim_val_r = cpu_reg_val WIM s';
psr_val_r = cpu_reg_val PSR s';
et_val_r = get_ET psr_val_r;
s_val_r = (ucast (get_S psr_val_r))::word1;
op_list_r = snd instr;
addr_r = get_addr (snd instr) s'
in
if et_val_r = 1 then True
else if s_val_r = 0 then False
else if (get_WIM_bit (nat new_cwp_int_r) wim_val_r) ≠ 0 then False
else if ((AND) addr_r (0b00000000000000000000000000000011::word32)) ≠ 0 then False
else True
else True
else False
)
)
"
function (sequential) seq_exec:: "nat ⇒ ('a::len,unit) sparc_state_monad"
where "seq_exec 0 = return ()"
|
"seq_exec n = (do execute_instruction();
(seq_exec (n-1))
od)
"
by pat_completeness auto
termination by lexicographic_order
type_synonym leon3_state = "(word_length5) sparc_state"
type_synonym ('e) leon3_state_monad = "(leon3_state, 'e) det_monad"
definition execute_leon3_instruction:: "unit ⇒ (unit) leon3_state_monad"
where "execute_leon3_instruction ≡ execute_instruction"
definition seq_exec_leon3:: "nat ⇒ (unit) leon3_state_monad"
where "seq_exec_leon3 ≡ seq_exec"
end
Theory Sparc_Properties
theory Sparc_Properties
imports Main Sparc_Execution
begin
section‹Single step theorem›
text ‹The following shows that, if the pre-state satisfies certain
conditions called ‹good_context›, there must be a defined post-state
after a single step execution.›
method save_restore_proof =
((simp add: save_restore_instr_def),
(simp add: Let_def simpler_gets_def bind_def h1_def h2_def),
(simp add: case_prod_unfold),
(simp add: raise_trap_def simpler_modify_def),
(simp add: simpler_gets_def bind_def h1_def h2_def),
(simp add: save_retore_sub1_def),
(simp add: write_cpu_def simpler_modify_def),
(simp add: write_reg_def simpler_modify_def),
(simp add: get_curr_win_def),
(simp add: simpler_gets_def bind_def h1_def h2_def))
method select_trap_proof0 =
((simp add: select_trap_def exec_gets return_def),
(simp add: DetMonad.bind_def h1_def h2_def simpler_modify_def),
(simp add: write_cpu_tt_def write_cpu_def),
(simp add: DetMonad.bind_def h1_def h2_def simpler_modify_def),
(simp add: return_def simpler_gets_def))
method select_trap_proof1 =
((simp add: select_trap_def exec_gets return_def),
(simp add: DetMonad.bind_def h1_def h2_def simpler_modify_def),
(simp add: write_cpu_tt_def write_cpu_def),
(simp add: DetMonad.bind_def h1_def h2_def simpler_modify_def),
(simp add: return_def simpler_gets_def),
(simp add: emp_trap_set_def err_mode_val_def cpu_reg_mod_def))
method dispatch_instr_proof1 =
((simp add: dispatch_instruction_def),
(simp add: simpler_gets_def bind_def h1_def h2_def),
(simp add: Let_def))
method exe_proof_to_decode =
((simp add: execute_instruction_def),
(simp add: exec_gets bind_def h1_def h2_def Let_def return_def),
clarsimp,
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def simpler_modify_def),
(simp add: return_def))
method exe_proof_dispatch_rett =
((simp add: dispatch_instruction_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def),
(simp add: rett_instr_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def))
lemma write_cpu_result: "snd (write_cpu w r s) = False"
by (simp add: write_cpu_def simpler_modify_def)
lemma set_annul_result: "snd (set_annul b s) = False"
by (simp add: set_annul_def simpler_modify_def)
lemma raise_trap_result : "snd (raise_trap t s) = False"
by (simp add: raise_trap_def simpler_modify_def)
lemma rett_instr_result: "(fst i) = ctrl_type RETT ∧
(get_ET (cpu_reg_val PSR s) ≠ 1 ∧
(((get_S (cpu_reg_val PSR s)))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s)) = 0 ∧
((AND) (get_addr (snd i) s) (0b00000000000000000000000000000011::word32)) = 0) ⟹
snd (rett_instr i s) = False"
apply (simp add: rett_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (auto simp add: Let_def return_def)
done
lemma call_instr_result: "(fst i) = call_type CALL ⟹
snd (call_instr i s) = False"
apply (simp add: call_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def case_prod_unfold)
apply (simp add: write_cpu_def write_reg_def)
apply (simp add: get_curr_win_def get_CWP_def)
by (simp add: simpler_modify_def simpler_gets_def)
lemma branch_instr_result: "(fst i) ∈ {bicc_type BE,bicc_type BNE,bicc_type BGU,
bicc_type BLE,bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,bicc_type BN} ⟹
snd (branch_instr i s) = False"
proof (cases "eval_icc (fst i) (get_icc_N ((cpu_reg s) PSR)) (get_icc_Z ((cpu_reg s) PSR))
(get_icc_V ((cpu_reg s) PSR)) (get_icc_C ((cpu_reg s) PSR)) = 1")
case True
then have f1: "eval_icc (fst i) (get_icc_N ((cpu_reg s) PSR)) (get_icc_Z ((cpu_reg s) PSR))
(get_icc_V ((cpu_reg s) PSR)) (get_icc_C ((cpu_reg s) PSR)) = 1"
by auto
then show ?thesis
proof (cases "(fst i) = bicc_type BA ∧ get_operand_flag ((snd i)!0) = 1")
case True
then show ?thesis using f1
apply (simp add: branch_instr_def)
apply (simp add: Let_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: set_annul_def case_prod_unfold)
apply (simp add: write_cpu_def simpler_modify_def)
by (simp add: return_def)
next
case False
then have f2: "¬ (fst i = bicc_type BA ∧ get_operand_flag (snd i ! 0) = 1)" by auto
then show ?thesis using f1
apply (simp add: branch_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: branch_instr_sub1_def)
apply (simp add: Let_def)
apply auto
apply (simp add: write_cpu_def simpler_modify_def)
by (simp add: write_cpu_def simpler_modify_def)
qed
next
case False
then show ?thesis
apply (simp add: branch_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: branch_instr_sub1_def)
apply (simp add: Let_def)
apply auto
apply (simp add: Let_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: cpu_reg_mod_def set_annul_def simpler_modify_def)
by (simp add: write_cpu_def simpler_modify_def)
qed
lemma nop_instr_result: "(fst i) = nop_type NOP ⟹
snd (nop_instr i s) = False"
apply (simp add: nop_instr_def)
by (simp add: returnOk_def return_def)
lemma sethi_instr_result: "(fst i) = sethi_type SETHI ⟹
snd (sethi_instr i s) = False"
apply (simp add: sethi_instr_def)
apply (simp add: Let_def)
apply (simp add: get_curr_win_def get_CWP_def cpu_reg_val_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_reg_def simpler_modify_def)
by (simp add: return_def)
lemma jmpl_instr_result: "(fst i) = ctrl_type JMPL ⟹
snd (jmpl_instr i s) = False"
apply (simp add: jmpl_instr_def)
apply (simp add: get_curr_win_def get_CWP_def cpu_reg_val_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: write_cpu_def simpler_modify_def)
by (simp add: raise_trap_def simpler_modify_def)
lemma save_restore_instr_result: "(fst i) ∈ {ctrl_type SAVE,ctrl_type RESTORE} ⟹
snd (save_restore_instr i s) = False"
proof (cases "(fst i) = ctrl_type SAVE")
case True
then show ?thesis
by save_restore_proof
next
case False
then show ?thesis
by save_restore_proof
qed
lemma flush_instr_result: "(fst i) = load_store_type FLUSH ⟹
snd (flush_instr i s) = False"
apply (simp add: flush_instr_def)
by (simp add: simpler_gets_def bind_def h1_def h2_def simpler_modify_def)
lemma read_state_reg_instr_result: "(fst i) ∈ {sreg_type RDY,sreg_type RDPSR,
sreg_type RDWIM,sreg_type RDTBR} ⟹
snd (read_state_reg_instr i s) = False"
apply (simp add: read_state_reg_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def bind_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: raise_trap_def simpler_modify_def return_def)
apply (simp add: bind_def h1_def h2_def)
by (simp add: get_curr_win_def simpler_gets_def)
lemma write_state_reg_instr_result: "(fst i) ∈ {sreg_type WRY,sreg_type WRPSR,
sreg_type WRWIM,sreg_type WRTBR} ⟹
snd (write_state_reg_instr i s) = False"
apply (simp add: write_state_reg_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_modify_def)
apply (simp add: raise_trap_def simpler_modify_def return_def)
apply (simp add: bind_def h1_def h2_def)
apply (simp add: simpler_gets_def)
apply (simp add: write_cpu_def simpler_modify_def)
by (simp add: get_curr_win_def simpler_gets_def)
lemma logical_instr_result: "(fst i) ∈ {logic_type ANDs,logic_type ANDcc,
logic_type ANDN,logic_type ANDNcc,logic_type ORs,logic_type ORcc,
logic_type ORN,logic_type XORs,logic_type XNOR} ⟹
snd (logical_instr i s) = False"
apply (simp add: logical_instr_def)
apply (simp add: Let_def simpler_gets_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: logical_instr_sub1_def)
apply (simp add: return_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def)
by (simp add: get_curr_win_def simpler_gets_def)
lemma shift_instr_result: "(fst i) ∈ {shift_type SLL,shift_type
SRL,shift_type SRA} ⟹
snd (shift_instr i s) = False"
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: get_curr_win_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: return_def)
apply (simp add: bind_def h1_def h2_def)
by (simp add: write_reg_def simpler_modify_def)
method add_sub_instr_proof =
((simp add: Let_def),
auto,
(simp add: write_reg_def simpler_modify_def),
(simp add: simpler_gets_def bind_def),
(simp add: get_curr_win_def simpler_gets_def),
(simp add: write_reg_def write_cpu_def simpler_modify_def),
(simp add: bind_def),
(simp add: case_prod_unfold),
(simp add: simpler_gets_def),
(simp add: get_curr_win_def simpler_gets_def),
(simp add: write_reg_def simpler_modify_def),
(simp add: simpler_gets_def bind_def),
(simp add: get_curr_win_def simpler_gets_def))
lemma add_instr_result: "(fst i) ∈ {arith_type ADD,arith_type
ADDcc,arith_type ADDX} ⟹
snd (add_instr i s) = False"
apply (simp add: add_instr_def)
apply (simp add: Let_def)
apply auto
apply (simp add: add_instr_sub1_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: add_instr_sub1_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: add_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: get_curr_win_def simpler_gets_def)
by (simp add: write_reg_def simpler_modify_def)
lemma sub_instr_result: "(fst i) ∈ {arith_type SUB,arith_type SUBcc,
arith_type SUBX} ⟹
snd (sub_instr i s) = False"
apply (simp add: sub_instr_def)
apply (simp add: Let_def)
apply auto
apply (simp add: sub_instr_sub1_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: sub_instr_sub1_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: sub_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: get_curr_win_def simpler_gets_def)
by (simp add: write_reg_def simpler_modify_def)
lemma mul_instr_result: "(fst i) ∈ {arith_type UMUL,arith_type SMUL,
arith_type SMULcc} ⟹
snd (mul_instr i s) = False"
apply (simp add: mul_instr_def)
apply (simp add: Let_def)
apply auto
apply (simp add: mul_instr_sub1_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: write_reg_def write_cpu_def simpler_modify_def)
apply (simp add: mul_instr_sub1_def)
apply (simp add: simpler_gets_def)
apply (simp add: write_cpu_def write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: get_curr_win_def simpler_gets_def)
apply (simp add: mul_instr_sub1_def)
apply (simp add: simpler_gets_def)
apply (simp add: write_cpu_def write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def)
by (simp add: get_curr_win_def simpler_gets_def)
lemma div_write_new_val_result: "snd (div_write_new_val i result temp_V s) = False"
apply (simp add: div_write_new_val_def)
apply (simp add: return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
by (simp add: write_cpu_def simpler_modify_def)
lemma div_result: "snd (div_comp instr rs1 rd operand2 s) = False"
apply (simp add: div_comp_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: get_curr_win_def simpler_gets_def)
by (simp add: div_write_new_val_result)
lemma div_instr_result: "(fst i) ∈ {arith_type UDIV,arith_type UDIVcc,
arith_type SDIV} ⟹
snd (div_instr i s) = False"
apply (simp add: div_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: return_def bind_def)
by (simp add: div_result)
lemma load_sub2_result: "snd (load_sub2 address asi rd curr_win word0 s) = False"
apply (simp add: load_sub2_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: bind_def h1_def h2_def)
apply (simp add: write_reg_def simpler_modify_def)
by (simp add: simpler_gets_def)
lemma load_sub3_result: "snd (load_sub3 instr curr_win rd asi address s) = False"
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: write_reg_def simpler_modify_def)
apply (simp add: load_sub2_result)
by (simp add: raise_trap_def simpler_modify_def)
lemma load_sub1_result: "snd (load_sub1 i rd s_val s) = False"
apply (simp add: load_sub1_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: get_curr_win_def simpler_gets_def)
by (simp add: load_sub3_result)
lemma load_instr_result: "(fst i) ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD} ⟹
snd (load_instr i s) = False"
apply (simp add: load_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: return_def)
by (simp add: load_sub1_result)
lemma store_sub2_result: "snd (store_sub2 instr curr_win rd asi address s) = False"
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: return_def)
apply (simp add: raise_trap_def simpler_modify_def)
by (simp add: bind_def h1_def h2_def)
lemma store_sub1_result: "snd (store_sub1 instr rd s_val s) = False"
apply (simp add: store_sub1_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: get_curr_win_def)
apply (simp add: simpler_gets_def)
by (simp add: store_sub2_result)
lemma store_instr_result: "(fst i) ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD} ⟹
snd (store_instr i s) = False"
apply (simp add: store_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: raise_trap_def simpler_modify_def)
apply (simp add: return_def)
by (simp add: store_sub1_result)
lemma supported_instr_set: "supported_instruction i = True ⟹
i ∈ {load_store_type LDSB,load_store_type LDUB,load_store_type LDUBA,
load_store_type LDUH,load_store_type LD,load_store_type LDA,
load_store_type LDD,
load_store_type STB,load_store_type STH,load_store_type ST,
load_store_type STA,load_store_type STD,
sethi_type SETHI,
nop_type NOP,
logic_type ANDs,logic_type ANDcc,logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
ctrl_type RETT,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
apply (simp add: supported_instruction_def)
by presburger
lemma dispatch_instr_result:
assumes a1: "supported_instruction (fst i) = True ∧ (fst i) ≠ ctrl_type RETT"
shows "snd (dispatch_instruction i s) = False"
proof (cases "get_trap_set s = {}")
case True
then have f1: "get_trap_set s = {}" by auto
then show ?thesis
proof (cases "(fst i) ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (simp add: load_instr_result)
next
case False
then have f2: "(fst i) ∈ {load_store_type STB,load_store_type STH,load_store_type ST,
load_store_type STA,load_store_type STD,
sethi_type SETHI,
nop_type NOP,
logic_type ANDs,logic_type ANDcc,logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using a1
apply (simp add: supported_instruction_def)
by presburger
then show ?thesis
proof (cases "(fst i) ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,
load_store_type STA,load_store_type STD}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: store_instr_result)
next
case False
then have f3: "(fst i) ∈ {sethi_type SETHI,
nop_type NOP,
logic_type ANDs,logic_type ANDcc,logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f2 by auto
then show ?thesis
proof (cases "(fst i) = sethi_type SETHI")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (simp add: sethi_instr_result)
next
case False
then have f4: "(fst i) ∈ {nop_type NOP,
logic_type ANDs,logic_type ANDcc,logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f3 by auto
then show ?thesis
proof (cases "fst i = nop_type NOP")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (simp add: nop_instr_result)
next
case False
then have f5: "(fst i) ∈ {logic_type ANDs,logic_type ANDcc,
logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR,
shift_type SLL,shift_type SRL,shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f4 by auto
then show ?thesis
proof (cases "(fst i) ∈ {logic_type ANDs,logic_type ANDcc,
logic_type ANDN,logic_type ANDNcc,
logic_type ORs,logic_type ORcc,logic_type ORN,logic_type XORs,
logic_type XNOR}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: logical_instr_result)
next
case False
then have f6: "(fst i) ∈ {shift_type SLL,shift_type SRL,
shift_type SRA,
arith_type ADD,arith_type ADDcc,arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f5 by auto
then show ?thesis
proof (cases "(fst i) ∈ {shift_type SLL,shift_type SRL,
shift_type SRA}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: shift_instr_result)
next
case False
then have f7: "(fst i) ∈ {arith_type ADD,arith_type ADDcc,
arith_type ADDX,
arith_type SUB,arith_type SUBcc,arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f6 by auto
then show ?thesis
proof (cases "(fst i) ∈ {arith_type ADD,arith_type ADDcc,
arith_type ADDX}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: add_instr_result)
next
case False
then have f8: "(fst i) ∈ {arith_type SUB,arith_type SUBcc,
arith_type SUBX,
arith_type UMUL,arith_type SMUL,arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f7 by auto
then show ?thesis
proof (cases "(fst i) ∈ {arith_type SUB,arith_type SUBcc,
arith_type SUBX}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: sub_instr_result)
next
case False
then have f9: "(fst i) ∈ {arith_type UMUL,arith_type SMUL,
arith_type SMULcc,
arith_type UDIV,arith_type UDIVcc,arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f8 by auto
then show ?thesis
proof (cases "(fst i) ∈ {arith_type UMUL,arith_type SMUL,
arith_type SMULcc}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: mul_instr_result)
next
case False
then have f10: "(fst i) ∈ {arith_type UDIV,arith_type UDIVcc,
arith_type SDIV,
ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f9 by auto
then show ?thesis
proof (cases "(fst i) ∈ {arith_type UDIV,arith_type UDIVcc,
arith_type SDIV}")
case True
then show ?thesis
apply dispatch_instr_proof1 using f1
by (auto simp add: div_instr_result)
next
case False
then have f11: "(fst i) ∈ {ctrl_type SAVE,ctrl_type RESTORE,
call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f10 by auto
then show ?thesis
proof (cases "(fst i) ∈ {ctrl_type SAVE,ctrl_type RESTORE}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: save_restore_instr_result)
next
case False
then have f12: "(fst i) ∈ {call_type CALL,
ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f11 by auto
then show ?thesis
proof (cases "(fst i) = call_type CALL")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: call_instr_result)
next
case False
then have f13: "(fst i) ∈ {ctrl_type JMPL,
sreg_type RDY,sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f12 by auto
then show ?thesis
proof (cases "(fst i) = ctrl_type JMPL")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: jmpl_instr_result)
next
case False
then have f14: "(fst i) ∈ {
sreg_type RDY,
sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR,
sreg_type WRY,sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f13 by auto
then show ?thesis
proof (cases "(fst i) ∈ {sreg_type RDY,
sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: read_state_reg_instr_result)
next
case False
then have f15: "(fst i) ∈ {
sreg_type WRY,
sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR,
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f14 by auto
then show ?thesis
proof (cases "(fst i) ∈ {sreg_type WRY,
sreg_type WRPSR,sreg_type WRWIM,sreg_type WRTBR}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: write_state_reg_instr_result)
next
case False
then have f16: "(fst i) ∈ {
load_store_type FLUSH,
bicc_type BE,bicc_type BNE,bicc_type BGU,bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f15 by auto
then show ?thesis
proof (cases "(fst i) = load_store_type FLUSH")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
by (auto simp add: flush_instr_result)
next
case False
then have f17: "(fst i) ∈
{
bicc_type BE,bicc_type BNE,bicc_type BGU,
bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA,
bicc_type BN}"
using f16 by auto
then show ?thesis using f1
proof (cases "(fst i) ∈ {bicc_type BE,
bicc_type BNE,bicc_type BGU,
bicc_type BLE,
bicc_type BL,bicc_type BGE,bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,bicc_type BA
}")
case True
then show ?thesis using f1
apply dispatch_instr_proof1
apply auto
by (auto simp add: branch_instr_result)
next
case False
then have f18: "(fst i) ∈ {bicc_type BN}"
using f17 by auto
then show ?thesis using f1
apply dispatch_instr_proof1
apply auto
by (auto simp add: branch_instr_result)
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
next
case False
then show ?thesis
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
by (simp add: returnOk_def return_def)
qed
lemma dispatch_instr_result_rett:
assumes a1: "(fst i) = ctrl_type RETT ∧ (get_ET (cpu_reg_val PSR s) ≠ 1 ∧
(((get_S (cpu_reg_val PSR s)))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s)) = 0 ∧
((AND) (get_addr (snd i) s) (0b00000000000000000000000000000011::word32)) = 0)"
shows "snd (dispatch_instruction i s) = False"
proof (cases "get_trap_set s = {}")
case True
then show ?thesis using a1
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: rett_instr_result)
next
case False
then show ?thesis using a1
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: return_def)
qed
lemma execute_instr_sub1_result: "snd (execute_instr_sub1 i s) = False"
proof (cases "get_trap_set s = {} ∧ (fst i) ∈ {call_type CALL,ctrl_type RETT,
ctrl_type JMPL}")
case True
then show ?thesis
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply auto
by (auto simp add: return_def)
next
case False
then show ?thesis
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
by (auto simp add: return_def)
qed
lemma next_match : "snd (execute_instruction () s) = False ⟹
NEXT s = Some (snd (fst (execute_instruction () s)))"
apply (simp add: NEXT_def)
by (simp add: case_prod_unfold)
lemma exec_ss1 : "∃s'. (execute_instruction () s = (s', False)) ⟹
∃s''. (execute_instruction() s = (s'', False))"
proof -
assume "∃s'. (execute_instruction () s = (s', False))"
hence "(snd (execute_instruction() s)) = False"
by (auto simp add: execute_instruction_def case_prod_unfold)
hence "(execute_instruction() s) =
((fst (execute_instruction() s)),False)"
by (metis (full_types) prod.collapse)
hence "∃s''. (execute_instruction() s = (s'', False))"
by blast
thus ?thesis by assumption
qed
lemma exec_ss2 : "snd (execute_instruction() s) = False ⟹
snd (execute_instruction () s) = False"
proof -
assume "snd (execute_instruction() s) = False"
hence "snd (execute_instruction () s) = False"
by (auto simp add:execute_instruction_def)
thus ?thesis by assumption
qed
lemma good_context_1 : "good_context s ∧ s' = s ∧
(get_trap_set s') ≠ {} ∧ (reset_trap_val s') = False ∧ get_ET (cpu_reg_val PSR s') = 0
⟹ False"
proof -
assume asm: "good_context s ∧ s' = s ∧
(get_trap_set s') ≠ {} ∧ (reset_trap_val s') = False ∧ get_ET (cpu_reg_val PSR s') = 0"
then have "(get_trap_set s') ≠ {} ∧ (reset_trap_val s') = False ∧
get_ET (cpu_reg_val PSR s') = 0 ⟹ False"
by (simp add: good_context_def get_ET_def cpu_reg_val_def)
then show ?thesis using asm by auto
qed
lemma fetch_instr_result_1 : "¬ (∃e. fetch_instruction s' = Inl e) ⟹
(∃v. fetch_instruction s' = Inr v)"
by (meson sumE)
lemma fetch_instr_result_2 : "(∃v. fetch_instruction s' = Inr v) ⟹
¬ (∃e. fetch_instruction s' = Inl e)"
by force
lemma fetch_instr_result_3 : "(∃e. fetch_instruction s' = Inl e) ⟹
¬ (∃v. fetch_instruction s' = Inr v)"
by auto
lemma decode_instr_result_1 :
"¬(∃v2. ((decode_instruction v1)::(Exception list + instruction)) = Inr v2) ⟹
(∃e. ((decode_instruction v1)::(Exception list + instruction)) = Inl e)"
by (meson sumE)
lemma decode_instr_result_2 :
"(∃e. ((decode_instruction v1)::(Exception list + instruction)) = Inl e) ⟹
¬(∃v2. ((decode_instruction v1)::(Exception list + instruction)) = Inr v2)"
by force
lemma decode_instr_result_3 : "x = decode_instruction v1 ∧ y = decode_instruction v2
∧ v1 = v2 ⟹ x = y"
by auto
lemma decode_instr_result_4 :
"¬ (∃e. ((decode_instruction v1)::(Exception list + instruction)) = Inl e) ⟹
(∃v2. ((decode_instruction v1)::(Exception list + instruction)) = Inr v2)"
by (meson sumE)
lemma good_context_2 :
"good_context (s::(('a::len) sparc_state)) ∧
fetch_instruction (delayed_pool_write s) = Inr v1 ∧
¬(∃v2. (decode_instruction v1::(Exception list + instruction)) = Inr v2)
⟹ False"
proof -
assume "good_context s ∧
fetch_instruction (delayed_pool_write s) = Inr v1 ∧
¬(∃v2. ((decode_instruction v1)::(Exception list + instruction)) = Inr v2)"
hence fact1: "good_context s ∧
fetch_instruction (delayed_pool_write s) = Inr v1 ∧
(∃e. ((decode_instruction v1)::(Exception list + instruction)) = Inl e)"
using decode_instr_result_1 by auto
hence fact2: "¬(∃e. fetch_instruction (delayed_pool_write s) = Inl e)"
using fetch_instr_result_2 by auto
then have "fetch_instruction (delayed_pool_write s) = Inr v1 ∧
(∃e. ((decode_instruction v1)::(Exception list + instruction)) = Inl e)
⟹ False"
proof (cases "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0")
case True
from this fact1 show ?thesis using good_context_1 by blast
next
case False
then have fact3: "(get_trap_set s) = {} ∨ (reset_trap_val s) ≠ False
∨ get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
then show ?thesis
using fact1 decode_instr_result_3
by (metis (no_types, lifting) good_context_def sum.case(1) sum.case(2))
qed
thus ?thesis using fact1 by auto
qed
lemma good_context_3 :
"good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
(decode_instruction v1::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = False
⟹ False"
proof -
assume asm: "good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
(decode_instruction v1::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = False"
then have "annul_val s'' = False ∧ supported_instruction (fst v2) = False
⟹ False"
proof (cases "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0")
case True
from this asm show ?thesis using good_context_1 by blast
next
case False
then have fact3: "(get_trap_set s) = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
thus ?thesis using asm by (auto simp add: good_context_def)
qed
thus ?thesis using asm by auto
qed
lemma good_context_4 :
"good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) = 0
⟹ False"
proof -
assume asm: "good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) = 0"
then have "(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) = 0 ⟹ False"
proof (cases "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0")
case True
from this asm show ?thesis using good_context_1 by blast
next
case False
then have fact3: "(get_trap_set s) = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
thus ?thesis using asm by (auto simp add: good_context_def)
qed
thus ?thesis using asm by auto
qed
lemma good_context_5 :
"good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) ≠ 0
⟹ False"
proof -
assume asm: "good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) ≠ 0"
then have "(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) ≠ 0
⟹ False"
proof (cases "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0")
case True
from this asm show ?thesis using good_context_1 by blast
next
case False
then have fact3: "(get_trap_set s) = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
thus ?thesis using asm by (auto simp add: good_context_def)
qed
thus ?thesis using asm by auto
qed
lemma good_context_6 :
"good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) = 0 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) ≠ 0
⟹ False"
proof -
assume asm: "good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ∧
fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧
supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) = 0 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) ≠ 0"
then have "(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) = 0 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) ≠ 0
⟹ False"
proof (cases "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0")
case True
from this asm show ?thesis using good_context_1 by blast
next
case False
then have fact3: "(get_trap_set s) = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
thus ?thesis using asm by (auto simp add: good_context_def)
qed
thus ?thesis using asm by auto
qed
lemma good_context_all :
"good_context (s::(('a::len) sparc_state)) ∧
s'' = delayed_pool_write s ⟹
(get_trap_set s = {} ∨ (reset_trap_val s) ≠ False ∨ get_ET (cpu_reg_val PSR s) ≠ 0) ∧
((∃e. fetch_instruction s'' = Inl e) ∨
(∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(annul_val s'' = True ∨
(annul_val s'' = False ∧
(∀v1' v2'. fetch_instruction s'' = Inr v1' ∧
((decode_instruction v1')::(Exception list + instruction)) = Inr v2' ⟶
supported_instruction (fst v2') = True) ∧
((fst v2) ≠ ctrl_type RETT ∨
((fst v2) = ctrl_type RETT ∧
(get_ET (cpu_reg_val PSR s'') = 1 ∨
(get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) = 0 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) = 0))))))))"
proof -
assume asm: "good_context s ∧ s'' = delayed_pool_write s"
from asm have "(get_trap_set s) ≠ {} ∧ (reset_trap_val s) = False ∧
get_ET (cpu_reg_val PSR s) = 0 ⟹ False"
using good_context_1 by blast
hence fact1: "(get_trap_set s = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0)" by auto
have fact2: "¬(∃e. fetch_instruction s'' = Inl e) ∧ ¬ (∃v1. fetch_instruction s'' = Inr v1)
⟹ False" using fetch_instr_result_1 by blast
from asm have fact3: "∃v1. fetch_instruction s'' = Inr v1 ∧
¬(∃v2.((decode_instruction v1)::(Exception list + instruction)) = Inr v2)
⟹ False"
using good_context_2 by blast
from asm have fact4: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = False
⟹ False"
using good_context_3 by blast
from asm have fact5: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) = 0
⟹ False"
using good_context_4 by blast
from asm have fact6: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) ≠ 0
⟹ False"
using good_context_5 by blast
from asm have fact7: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT ∧ get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1) mod NWINDOWS))
(cpu_reg_val WIM s'')) = 0 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) ≠ 0
⟹ False"
using good_context_6 by blast
from asm show ?thesis
proof (cases "(∃e. fetch_instruction s'' = Inl e)")
case True
then show ?thesis using fact1 by auto
next
case False
then have fact8: "∃v1. fetch_instruction s'' = Inr v1 ∧
(∃v2.((decode_instruction v1)::(Exception list + instruction)) = Inr v2)"
using fact2 fact3 by auto
then show ?thesis
proof (cases "annul_val s'' = True")
case True
then show ?thesis using fact1 fact8 by auto
next
case False
then have fact9: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = True"
using fact4 fact8 by blast
then show ?thesis
proof (cases "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) ≠ ctrl_type RETT")
case True
then show ?thesis using fact1 fact9 by auto
next
case False
then have fact10: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val s'' = False ∧ supported_instruction (fst v2) = True ∧
(fst v2) = ctrl_type RETT"
using fact9 by auto
then show ?thesis
proof (cases "get_ET (cpu_reg_val PSR s'') = 1")
case True
then show ?thesis using fact1 fact9 by auto
next
case False
then have fact11: "get_ET (cpu_reg_val PSR s'') ≠ 1 ∧
(((get_S (cpu_reg_val PSR s'')))::word1) ≠ 0"
using fact10 fact5 by auto
then have fact12: "(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR s''))) + 1)
mod NWINDOWS)) (cpu_reg_val WIM s'')) = 0"
using fact10 fact6 by auto
then have fact13: "∃v1 v2. fetch_instruction s'' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
((AND) (get_addr (snd v2) s'') (0b00000000000000000000000000000011::word32)) = 0"
using fact10 fact11 fact7 by blast
thus ?thesis using fact1 fact10 fact11 fact12 by auto
qed
qed
qed
qed
qed
lemma select_trap_result1 : "(reset_trap_val s) = True ⟹
snd (select_trap() s) = False"
apply (simp add: select_trap_def exec_gets return_def)
by (simp add: bind_def h1_def h2_def simpler_modify_def)
lemma select_trap_result2 :
assumes a1: "¬(reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) = 0)"
shows "snd (select_trap() s) = False"
proof (cases "reset_trap_val s = True")
case True
then show ?thesis using select_trap_result1
by blast
next
case False
then have f1: "reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) ≠ 0"
using a1 by auto
then show ?thesis
proof (cases "data_store_error ∈ get_trap_set s")
case True
then show ?thesis using f1
by select_trap_proof0
next
case False
then have f2: "data_store_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "instruction_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2
by select_trap_proof0
next
case False
then have f3: "instruction_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "r_register_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3
by select_trap_proof0
next
case False
then have f4: "r_register_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "instruction_access_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4
by select_trap_proof0
next
case False
then have f5: "instruction_access_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "privileged_instruction ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5
by select_trap_proof0
next
case False
then have f6: "privileged_instruction ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "illegal_instruction ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6
by select_trap_proof0
next
case False
then have f7: "illegal_instruction ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "fp_disabled ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7
by select_trap_proof0
next
case False
then have f8: "fp_disabled ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "cp_disabled ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8
by select_trap_proof0
next
case False
then have f9: "cp_disabled ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "unimplemented_FLUSH ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9
by select_trap_proof0
next
case False
then have f10: "unimplemented_FLUSH ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "window_overflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
by select_trap_proof0
next
case False
then have f11: "window_overflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "window_underflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
by select_trap_proof0
next
case False
then have f12: "window_underflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "mem_address_not_aligned ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
by select_trap_proof0
next
case False
then have f13: "mem_address_not_aligned ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "fp_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
by select_trap_proof0
next
case False
then have f14: "fp_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "cp_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
f14
by select_trap_proof0
next
case False
then have f15: "cp_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "data_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
f14 f15
by select_trap_proof0
next
case False
then have f16: "data_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "data_access_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15 f16
by select_trap_proof0
next
case False
then have f17: "data_access_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "tag_overflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15 f16 f17
by select_trap_proof0
next
case False
then have f18: "tag_overflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "division_by_zero ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18
by select_trap_proof0
next
case False
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18
apply (simp add: select_trap_def exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def simpler_modify_def)
apply (simp add: return_def simpler_gets_def)
apply (simp add: case_prod_unfold)
apply (simp add: return_def)
apply (simp add: write_cpu_tt_def write_cpu_def)
by (simp add: simpler_gets_def bind_def h1_def h2_def simpler_modify_def)
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
lemma emp_trap_set_err_mode : "err_mode_val s = err_mode_val (emp_trap_set s)"
by (auto simp add: emp_trap_set_def err_mode_val_def)
lemma write_cpu_tt_err_mode : "err_mode_val s = err_mode_val (snd (fst (write_cpu_tt w s)))"
apply (simp add: write_cpu_tt_def err_mode_val_def write_cpu_def)
apply (simp add: exec_gets return_def)
apply (simp add: bind_def simpler_modify_def)
by (simp add: cpu_reg_mod_def)
lemma select_trap_monad : "snd (select_trap() s) = False ⟹
err_mode_val s = err_mode_val (snd (fst (select_trap () s)))"
proof -
assume a1: "snd (select_trap() s) = False"
then have f0: "reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) = 0 ⟹ False"
apply (simp add: select_trap_def exec_gets return_def)
apply (simp add: bind_def h1_def h2_def simpler_modify_def)
by (simp add: fail_def split_def)
then show ?thesis
proof (cases "reset_trap_val s = True")
case True
from a1 f0 this show ?thesis
apply (simp add: select_trap_def exec_gets return_def)
apply (simp add: bind_def h1_def h2_def simpler_modify_def)
by (simp add: emp_trap_set_def err_mode_val_def)
next
case False
then have f1: "reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) ≠ 0" using f0 by auto
then show ?thesis using f1 a1
proof (cases "data_store_error ∈ get_trap_set s")
case True
then show ?thesis using f1 a1
by select_trap_proof1
next
case False
then have f2: "data_store_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "instruction_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 a1
by select_trap_proof1
next
case False
then have f3: "instruction_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "r_register_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 a1
by select_trap_proof1
next
case False
then have f4: "r_register_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "instruction_access_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 a1
by select_trap_proof1
next
case False
then have f5: "instruction_access_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "privileged_instruction ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 a1
by select_trap_proof1
next
case False
then have f6: "privileged_instruction ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "illegal_instruction ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 a1
by select_trap_proof1
next
case False
then have f7: "illegal_instruction ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "fp_disabled ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 a1
by select_trap_proof1
next
case False
then have f8: "fp_disabled ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "cp_disabled ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 a1
by select_trap_proof1
next
case False
then have f9: "cp_disabled ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "unimplemented_FLUSH ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 a1
by select_trap_proof1
next
case False
then have f10: "unimplemented_FLUSH ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "window_overflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 a1
by select_trap_proof1
next
case False
then have f11: "window_overflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "window_underflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 a1
by select_trap_proof1
next
case False
then have f12: "window_underflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "mem_address_not_aligned ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 a1
by select_trap_proof1
next
case False
then have f13: "mem_address_not_aligned ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "fp_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
a1
by select_trap_proof1
next
case False
then have f14: "fp_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "cp_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
f14 a1
by select_trap_proof1
next
case False
then have f15: "cp_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "data_access_error ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
f14 f15 a1
by select_trap_proof1
next
case False
then have f16: "data_access_error ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "data_access_exception ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15 f16 a1
by select_trap_proof1
next
case False
then have f17: "data_access_exception ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "tag_overflow ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15 f16 f17 a1
by select_trap_proof1
next
case False
then have f18: "tag_overflow ∉ get_trap_set s" by auto
then show ?thesis
proof (cases "division_by_zero ∈ get_trap_set s")
case True
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18 a1
by select_trap_proof1
next
case False
then show ?thesis using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18 a1
apply (simp add: select_trap_def exec_gets return_def)
apply (simp add: bind_def h1_def h2_def simpler_modify_def)
apply (simp add: return_def simpler_gets_def)
apply (simp add: emp_trap_set_def err_mode_val_def
cpu_reg_mod_def)
apply (simp add: case_prod_unfold)
apply (simp add: return_def)
apply clarsimp
apply (simp add: write_cpu_tt_def write_cpu_def write_tt_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: simpler_modify_def)
by (simp add: cpu_reg_val_def cpu_reg_mod_def)
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
lemma exe_trap_st_pc_result : "snd (exe_trap_st_pc() s) = False"
proof (cases "annul_val s = True")
case True
then show ?thesis
apply (simp add: exe_trap_st_pc_def get_curr_win_def)
apply (simp add: exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def)
by (simp add: set_annul_def write_reg_def simpler_modify_def)
next
case False
then show ?thesis
apply (simp add: exe_trap_st_pc_def get_curr_win_def)
apply (simp add: exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def)
by (simp add: write_reg_def simpler_modify_def)
qed
lemma exe_trap_wr_pc_result : "snd (exe_trap_wr_pc() s) = False"
proof (cases "reset_trap_val s = True")
case True
then show ?thesis
apply (simp add: exe_trap_wr_pc_def get_curr_win_def)
apply (simp add: exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: simpler_gets_def)
apply (simp add: cpu_reg_val_def update_S_def cpu_reg_mod_def reset_trap_val_def)
apply (simp add: write_cpu_def simpler_modify_def DetMonad.bind_def h1_def h2_def)
apply (simp add: return_def)
by (simp add: set_reset_trap_def simpler_modify_def DetMonad.bind_def h1_def h2_def return_def)
next
case False
then show ?thesis
apply (simp add: exe_trap_wr_pc_def get_curr_win_def)
apply (simp add: exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def)
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: simpler_gets_def)
apply (simp add: cpu_reg_val_def update_S_def cpu_reg_mod_def reset_trap_val_def)
apply (simp add: write_cpu_def simpler_modify_def DetMonad.bind_def h1_def h2_def)
by (simp add: return_def)
qed
lemma execute_trap_result : "¬(reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) = 0) ⟹
snd (execute_trap() s) = False"
proof -
assume "¬(reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) = 0)"
then have fact1: "snd (select_trap() s) = False" using select_trap_result2 by blast
then show ?thesis
proof (cases "err_mode_val s = True")
case True
then show ?thesis using fact1
apply (simp add: execute_trap_def exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (simp add: in_gets return_def select_trap_monad simpler_gets_def)
next
case False
then show ?thesis using fact1 select_trap_monad
apply (simp add: execute_trap_def exec_gets return_def)
apply (simp add: DetMonad.bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def)
apply (auto simp add: select_trap_monad)
apply (simp add: DetMonad.bind_def h1_def h2_def get_curr_win_def)
apply (simp add: get_CWP_def cpu_reg_val_def)
apply (simp add: simpler_gets_def return_def write_cpu_def)
apply (simp add: simpler_modify_def DetMonad.bind_def h1_def h2_def)
apply (simp add: exe_trap_st_pc_result)
by (simp add: case_prod_unfold exe_trap_wr_pc_result)
qed
qed
lemma execute_trap_result2 : "¬(reset_trap_val s = False ∧ get_ET (cpu_reg_val PSR s) = 0) ⟹
snd (execute_trap() s) = False"
using execute_trap_result
by blast
lemma exe_instr_all :
"good_context (s::(('a::len) sparc_state)) ⟹
snd (execute_instruction() s) = False"
proof -
assume asm1: "good_context s"
let ?s' = "delayed_pool_write s"
from asm1 have f1 : "(get_trap_set s = {} ∨ (reset_trap_val s) ≠ False ∨
get_ET (cpu_reg_val PSR s) ≠ 0) ∧
((∃e. fetch_instruction ?s' = Inl e) ∨
(∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(annul_val ?s' = True ∨
(annul_val ?s' = False ∧
(∀v1' v2'. fetch_instruction ?s' = Inr v1' ∧
((decode_instruction v1')::(Exception list + instruction)) = Inr v2' ⟶
supported_instruction (fst v2') = True) ∧
((fst v2) ≠ ctrl_type RETT ∨
((fst v2) = ctrl_type RETT ∧
(get_ET (cpu_reg_val PSR ?s') = 1 ∨
(get_ET (cpu_reg_val PSR ?s') ≠ 1 ∧
(((get_S (cpu_reg_val PSR ?s')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR ?s'))) + 1) mod NWINDOWS))
(cpu_reg_val WIM ?s')) = 0 ∧
((AND) (get_addr (snd v2) ?s') (0b00000000000000000000000000000011::word32)) = 0))))))))"
using good_context_all by blast
from f1 have f2: "get_trap_set s ≠ {} ⟹
(reset_trap_val s) ≠ False ∨ get_ET (cpu_reg_val PSR s) ≠ 0"
by auto
show ?thesis
proof (cases "get_trap_set s = {}")
case True
then have f3: "get_trap_set s = {}" by auto
then show ?thesis
proof (cases "exe_mode_val s = True")
case True
then have f4: "exe_mode_val s = True" by auto
then show ?thesis
proof (cases "∃e1. fetch_instruction ?s' = Inl e1")
case True
then show ?thesis using f3
apply exe_proof_to_decode
apply (simp add: raise_trap_def simpler_modify_def)
by (simp add: bind_def h1_def h2_def return_def)
next
case False
then have f5: "∃ v1. fetch_instruction ?s' = Inr v1" using fetch_instr_result_1 by blast
then have f6: "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2"
using f1 fetch_instr_result_2 by blast
then show ?thesis
proof (cases "annul_val ?s' = True")
case True
then show ?thesis using f3 f4 f6
apply exe_proof_to_decode
apply (simp add: set_annul_def annul_mod_def simpler_modify_def bind_def h1_def h2_def)
apply (simp add: return_def simpler_gets_def)
by (simp add: write_cpu_def simpler_modify_def)
next
case False
then have f7: "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(∀v1' v2'. fetch_instruction ?s' = Inr v1' ∧
((decode_instruction v1')::(Exception list + instruction)) = Inr v2' ⟶
supported_instruction (fst v2') = True) ∧ annul_val ?s' = False"
using f1 f6 fetch_instr_result_2 by auto
then have f7': "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
supported_instruction (fst v2) = True ∧ annul_val ?s' = False"
by auto
then show ?thesis
proof (cases "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) = ctrl_type RETT")
case True
then have f8: "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) = ctrl_type RETT" by auto
then show ?thesis
proof (cases "get_trap_set ?s' = {}")
case True
then have f9: "get_trap_set ?s' = {}" by auto
then show ?thesis
proof (cases "get_ET (cpu_reg_val PSR ?s') = 1")
case True
then have f10: "get_ET (cpu_reg_val PSR ?s') = 1" by auto
then show ?thesis
proof (cases "(((get_S (cpu_reg_val PSR ?s')))::word1) = 0")
case True
then show ?thesis using f3 f4 f7 f8 f9 f10
apply exe_proof_to_decode
apply exe_proof_dispatch_rett
apply (simp add: raise_trap_def simpler_modify_def)
apply (auto simp add: execute_instr_sub1_result return_def)
by (simp add: case_prod_unfold)
next
case False
then show ?thesis using f3 f4 f7 f8 f9 f10
apply exe_proof_to_decode
apply exe_proof_dispatch_rett
apply (simp add: raise_trap_def simpler_modify_def)
apply (auto simp add: execute_instr_sub1_result return_def)
by (simp add: case_prod_unfold)
qed
next
case False
then have f11: "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
annul_val ?s' = False ∧
(fst v2) = ctrl_type RETT ∧
(get_ET (cpu_reg_val PSR ?s') ≠ 1 ∧
(((get_S (cpu_reg_val PSR ?s')))::word1) ≠ 0 ∧
(get_WIM_bit (nat (((uint (get_CWP (cpu_reg_val PSR ?s'))) + 1) mod NWINDOWS))
(cpu_reg_val WIM ?s')) = 0 ∧
((AND) (get_addr (snd v2) ?s') (0b00000000000000000000000000000011::word32)) = 0)"
using f1 fetch_instr_result_2 f7' f8 by auto
then show ?thesis using f3 f4
proof (cases "get_trap_set ?s' = {}")
case True
then show ?thesis using f3 f4 f11
apply (simp add: execute_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def simpler_modify_def)
apply clarsimp
apply (simp add: return_def)
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp add: execute_instr_sub1_result)
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: rett_instr_result)
next
case False
then show ?thesis using f3 f4 f11
apply (simp add: execute_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def simpler_modify_def)
apply clarsimp
apply (simp add: return_def)
apply (simp add: bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply (simp add: execute_instr_sub1_result)
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: return_def)
qed
qed
next
case False
then show ?thesis using f3 f4 f7 f8
apply exe_proof_to_decode
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
by (auto simp add: execute_instr_sub1_result return_def Let_def)
qed
next
case False
then have "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) ≠ ctrl_type RETT" using f7 by auto
then have "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) ≠ ctrl_type RETT ∧
supported_instruction (fst v2) = True ∧ annul_val ?s' = False"
using f7 by auto
then have "∃v1 v2. fetch_instruction ?s' = Inr v1 ∧
((decode_instruction v1)::(Exception list + instruction)) = Inr v2 ∧
(fst v2) ≠ ctrl_type RETT ∧
supported_instruction (fst v2) = True ∧ annul_val ?s' = False ∧
snd (dispatch_instruction v2 ?s') = False"
by (auto simp add: dispatch_instr_result)
then show ?thesis using f3 f4
apply exe_proof_to_decode
apply (simp add: bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
by (simp add: execute_instr_sub1_result)
qed
qed
qed
next
case False
then show ?thesis using f3
apply (simp add: execute_instruction_def)
by (simp add: exec_gets return_def)
qed
next
case False
then have "get_trap_set s ≠ {} ∧
((reset_trap_val s) ≠ False ∨ get_ET (cpu_reg_val PSR s) ≠ 0)"
using f2 by auto
then show ?thesis
apply (simp add: execute_instruction_def exec_gets)
by (simp add: execute_trap_result2)
qed
qed
lemma dispatch_fail:
"snd (execute_instruction() (s::(('a::len) sparc_state))) = False ∧
get_trap_set s = {} ∧
exe_mode_val s ∧
fetch_instruction (delayed_pool_write s) = Inr v ∧
((decode_instruction v)::(Exception list + instruction)) = Inl e
⟹ False"
using decode_instr_result_2
apply (simp add: execute_instruction_def)
apply (simp add: exec_gets bind_def)
apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: simpler_modify_def return_def)
by (simp add: fail_def)
lemma no_error : "good_context s ⟹ snd (execute_instruction () s) = False"
proof -
assume "good_context s"
hence "snd (execute_instruction() s) = False"
using exe_instr_all by auto
hence "snd (execute_instruction () s) = False" by (simp add: exec_ss2)
thus ?thesis by assumption
qed
theorem single_step : "good_context s ⟹ NEXT s = Some (snd (fst (execute_instruction () s)))"
by (simp add: no_error next_match)
section ‹Privilege safty›
text ‹The following shows that, if the pre-state is under user mode,
then after a singel step execution, the post-state is aslo under user mode.›
lemma write_cpu_pc_privilege: "s' = snd (fst (write_cpu w PC s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: cpu_reg_mod_def)
by (simp add: cpu_reg_val_def)
lemma write_cpu_npc_privilege: "s' = snd (fst (write_cpu w nPC s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: cpu_reg_mod_def)
by (simp add: cpu_reg_val_def)
lemma write_cpu_y_privilege: "s' = snd (fst (write_cpu w Y s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: cpu_reg_mod_def)
by (simp add: cpu_reg_val_def)
lemma cpu_reg_mod_y_privilege: "s' = cpu_reg_mod w Y s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
by (simp add: cpu_reg_mod_def cpu_reg_val_def)
lemma cpu_reg_mod_asr_privilege: "s' = cpu_reg_mod w (ASR r) s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
by (simp add: cpu_reg_mod_def cpu_reg_val_def)
lemma global_reg_mod_privilege: "s' = global_reg_mod w1 n w2 s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (induction n arbitrary:s)
apply (clarsimp)
apply (auto)
apply (simp add: Let_def)
by (simp add: cpu_reg_val_def)
lemma out_reg_mod_privilege: "s' = out_reg_mod a w r s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: out_reg_mod_def Let_def)
by (simp add: cpu_reg_val_def)
lemma in_reg_mod_privilege: "s' = in_reg_mod a w r s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: in_reg_mod_def Let_def)
by (simp add: cpu_reg_val_def)
lemma user_reg_mod_privilege:
assumes a1: " s' = user_reg_mod d (w::(('a::len) window_size)) r
(s::(('a::len) sparc_state)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "r = 0")
case True
then show ?thesis using a1
by (simp add: user_reg_mod_def)
next
case False
then have f1: "r ≠ 0" by auto
then show ?thesis
proof (cases "0 < r ∧ r < 8")
case True
then show ?thesis using a1 f1
apply (simp add: user_reg_mod_def)
by (auto intro: global_reg_mod_privilege)
next
case False
then have f2: "¬(0 < r ∧ r < 8)" by auto
then show ?thesis
proof (cases "7 < r ∧ r < 16")
case True
then show ?thesis using a1 f1 f2
apply (simp add: user_reg_mod_def)
by (auto intro: out_reg_mod_privilege)
next
case False
then have f3: "¬ (7 < r ∧ r < 16)" by auto
then show ?thesis
proof (cases "15 < r ∧ r < 24")
case True
then show ?thesis using a1 f1 f2 f3
apply (simp add: user_reg_mod_def)
by (simp add: cpu_reg_val_def)
next
case False
then show ?thesis using a1 f1 f2 f3
apply (simp add: user_reg_mod_def)
by (auto intro: in_reg_mod_privilege)
qed
qed
qed
qed
lemma write_reg_privilege: "s' = snd (fst (write_reg w1 w2 w3
(s::(('a::len) sparc_state)))) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: write_reg_def simpler_modify_def)
by (auto intro: user_reg_mod_privilege)
lemma set_annul_privilege: "s' = snd (fst (set_annul b s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: set_annul_def simpler_modify_def)
apply (simp add: annul_mod_def write_annul_def)
by (simp add: cpu_reg_val_def)
lemma set_reset_trap_privilege: "s' = snd (fst (set_reset_trap b s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: set_reset_trap_def simpler_modify_def)
apply (simp add: reset_trap_mod_def write_annul_def)
by (simp add: cpu_reg_val_def)
lemma empty_delayed_pool_write_privilege: "get_delayed_pool s = [] ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ∧
s' = delayed_pool_write s ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: delayed_pool_write_def)
by (simp add: get_delayed_write_def delayed_write_all_def delayed_pool_rm_list_def)
lemma raise_trap_privilege:
"(((get_S (cpu_reg_val PSR s)))::word1) = 0 ∧
s' = snd (fst (raise_trap t s)) ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: raise_trap_def)
apply (simp add: simpler_modify_def add_trap_set_def)
by (simp add: cpu_reg_val_def)
lemma write_cpu_tt_privilege: "s' = snd (fst (write_cpu_tt w s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: write_cpu_tt_def)
apply (simp add: exec_gets)
apply (simp add: write_cpu_def cpu_reg_mod_def write_tt_def)
apply (simp add: simpler_modify_def)
by (simp add: cpu_reg_val_def)
lemma emp_trap_set_privilege: "s' = emp_trap_set s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: emp_trap_set_def)
by (simp add: cpu_reg_val_def)
lemma sys_reg_mod_privilege: "s' = sys_reg_mod w r s
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: sys_reg_mod_def)
by (simp add: cpu_reg_val_def)
lemma mem_mod_privilege:
assumes a1: "s' = mem_mod a1 a2 v s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "(uint a1) = 8 ∨ (uint a1) = 10")
case True
then show ?thesis using a1
apply (simp add: mem_mod_def)
apply (simp add: Let_def)
by (simp add: cpu_reg_val_def)
next
case False
then have f1: "¬((uint a1) = 8 ∨ (uint a1) = 10)" by auto
then show ?thesis
proof (cases "(uint a1) = 9 ∨ (uint a1) = 11")
case True
then show ?thesis using a1 f1
apply (simp add: mem_mod_def)
apply (simp add: Let_def)
by (simp add: cpu_reg_val_def)
next
case False
then show ?thesis using a1 f1
apply (simp add: mem_mod_def)
by (simp add: cpu_reg_val_def)
qed
qed
lemma mem_mod_w32_privilege: "s' = mem_mod_w32 a1 a2 b d s ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: mem_mod_w32_def)
apply (simp add: Let_def)
by (auto intro: mem_mod_privilege)
lemma add_instr_cache_privilege: "s' = add_instr_cache s addr y m ⟹
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: add_instr_cache_def)
apply (simp add: Let_def)
by (simp add: icache_mod_def cpu_reg_val_def)
lemma add_data_cache_privilege: "s' = add_data_cache s addr y m ⟹
(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: add_data_cache_def)
apply (simp add: Let_def)
by (simp add: dcache_mod_def cpu_reg_val_def)
lemma memory_read_privilege:
assumes a1: "s' = snd (memory_read asi addr s) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "uint asi = 1")
case True
then show ?thesis using a1
apply (simp add: memory_read_def)
by (simp add: Let_def)
next
case False
then have f1: "uint asi ≠ 1" by auto
then show ?thesis
proof (cases "uint asi = 2")
case True
then show ?thesis using a1 f1
by (simp add: memory_read_def)
next
case False
then have f2: "uint asi ≠ 2" by auto
then show ?thesis
proof (cases "uint asi ∈ {8,9}")
case True
then have f3: "uint asi ∈ {8,9}" by auto
then show ?thesis
proof (cases "load_word_mem s addr asi = None")
case True
then have f4: "load_word_mem s addr asi = None" by auto
then show ?thesis
using a1 f1 f2 f3 f4
by (simp add: memory_read_def)
next
case False
then show ?thesis using a1 f1 f2 f3
apply (simp add: memory_read_def)
apply auto
apply (simp add: add_instr_cache_privilege)
by (simp add: add_instr_cache_privilege)
qed
next
case False
then have f5: "uint asi ∉ {8, 9}" by auto
then show ?thesis
proof (cases "uint asi ∈ {10,11}")
case True
then have f6: "uint asi ∈ {10,11}" by auto
then show ?thesis
proof (cases "load_word_mem s addr asi = None")
case True
then have f7: "load_word_mem s addr asi = None" by auto
then show ?thesis
using a1 f1 f2 f5 f6 f7
by (simp add: memory_read_def)
next
case False
then show ?thesis using a1 f1 f2 f5 f6
apply (simp add: memory_read_def)
apply auto
apply (simp add: add_data_cache_privilege)
by (simp add: add_data_cache_privilege)
qed
next
case False
then have f8: "uint asi ∉ {10,11}" by auto
then show ?thesis
proof (cases "uint asi = 13")
case True
then have f9: "uint asi = 13" by auto
then show ?thesis
proof (cases "read_instr_cache s addr = None")
case True
then show ?thesis using a1 f1 f2 f5 f8 f9
by (simp add: memory_read_def)
next
case False
then show ?thesis using a1 f1 f2 f5 f8 f9
apply (simp add: memory_read_def)
by auto
qed
next
case False
then have f10: "uint asi ≠ 13" by auto
then show ?thesis
proof (cases "uint asi = 15")
case True
then show ?thesis using a1 f1 f2 f5 f8 f10
apply (simp add: memory_read_def)
apply (cases "read_data_cache s addr = None")
by auto
next
case False
then show ?thesis using a1 f1 f2 f5 f8 f10
apply (simp add: memory_read_def)
by (simp add: Let_def)
qed
qed
qed
qed
qed
qed
lemma get_curr_win_privilege: "s' = snd (fst (get_curr_win() s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: get_curr_win_def)
by (simp add: simpler_gets_def)
lemma load_sub2_privilege:
assumes a1: "s' = snd (fst (load_sub2 addr asi r win w s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "fst (memory_read asi (addr + 4)
(snd (fst (write_reg w win (r AND 30) s)))) =
None")
case True
then show ?thesis using a1
apply (simp add: load_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (auto intro: raise_trap_privilege write_reg_privilege)
next
case False
then show ?thesis using a1
apply (simp add: load_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
by (auto intro: write_reg_privilege memory_read_privilege)
qed
lemma load_sub3_privilege:
assumes a1: "s' = snd (fst (load_sub3 instr curr_win rd asi address s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "fst (memory_read asi address s) = None")
case True
then show ?thesis using a1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
by (auto intro: raise_trap_privilege)
next
case False
then have f1: "fst (memory_read asi address s) ≠ None " by auto
then show ?thesis
proof (cases "rd ≠ 0 ∧
(fst instr = load_store_type LD ∨
fst instr = load_store_type LDA ∨
fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDSB ∨
fst instr = load_store_type LDUB ∨
fst instr = load_store_type LDUBA ∨
fst instr = load_store_type LDSH ∨
fst instr = load_store_type LDSHA ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSBA)")
case True
then show ?thesis using a1 f1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
by (auto intro: write_reg_privilege memory_read_privilege)
next
case False
then show ?thesis using a1 f1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp add: simpler_modify_def bind_def h1_def h2_def)
apply (auto intro: load_sub2_privilege memory_read_privilege)
apply (simp add: simpler_modify_def bind_def h1_def h2_def)
by (auto intro: load_sub2_privilege memory_read_privilege)
qed
qed
lemma load_sub1_privilege:
assumes a1: "s' = snd (fst (load_sub1 instr rd s_val s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: load_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
by (auto intro: get_curr_win_privilege raise_trap_privilege load_sub3_privilege)
lemma load_instr_privilege: "s' = snd (fst (load_instr i s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: load_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
apply clarsimp
by (auto intro: get_curr_win_privilege raise_trap_privilege load_sub1_privilege)
lemma store_barrier_pending_mod_privilege: "s' = store_barrier_pending_mod b s
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0
⟹ (((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: store_barrier_pending_mod_def)
apply (simp add: write_store_barrier_pending_def)
by (simp add: cpu_reg_val_def)
lemma store_word_mem_privilege:
assumes a1: "store_word_mem s addr data byte_mask asi = Some s' ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1 apply (simp add: store_word_mem_def)
apply (case_tac "virt_to_phys addr (mmu s) (mem s) = None")
apply auto
apply (case_tac "mmu_writable (get_acc_flag b) asi")
apply auto
by (simp add: mem_mod_w32_privilege)
lemma flush_instr_cache_privilege: "(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
s' = flush_instr_cache s ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: flush_instr_cache_def)
by (simp add: cpu_reg_val_def)
lemma flush_data_cache_privilege: "(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
s' = flush_data_cache s ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: flush_data_cache_def)
by (simp add: cpu_reg_val_def)
lemma flush_cache_all_privilege: "(((get_S (cpu_reg_val PSR s)))::word1) = 0 ⟹
s' = flush_cache_all s ⟹
(((get_S (cpu_reg_val PSR s')))::word1) = 0"
apply (simp add: flush_cache_all_def)
by (simp add: cpu_reg_val_def)
lemma memory_write_asi_privilege:
assumes a1: "r = memory_write_asi asi addr byte_mask data s ∧
r = Some s' ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "uint asi = 1")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
by (auto intro: store_word_mem_privilege)
next
case False
then have f1: "uint asi ≠ 1" by auto
then show ?thesis
proof (cases "uint asi = 2")
case True
then have f01: "uint asi = 2" by auto
then show ?thesis
proof (cases "uint addr = 0")
case True
then show ?thesis using a1 f1 f01
apply (simp add: memory_write_asi_def)
apply (simp add: ccr_flush_def)
apply (simp add: Let_def)
apply auto
apply (metis flush_data_cache_privilege flush_instr_cache_privilege sys_reg_mod_privilege)
apply (metis flush_instr_cache_privilege sys_reg_mod_privilege)
apply (metis flush_data_cache_privilege sys_reg_mod_privilege)
by (simp add: sys_reg_mod_privilege)
next
case False
then show ?thesis using a1 f1 f01
apply (simp add: memory_write_asi_def)
apply clarsimp
by (metis option.distinct(1) option.sel sys_reg_mod_privilege)
qed
next
case False
then have f2: "uint asi ≠ 2" by auto
then show ?thesis
proof (cases "uint asi ∈ {8,9}")
case True
then show ?thesis using a1 f1 f2
apply (simp add: memory_write_asi_def)
using store_word_mem_privilege add_instr_cache_privilege
by blast
next
case False
then have f3: "uint asi ∉ {8,9}" by auto
then show ?thesis
proof (cases "uint asi ∈ {10,11}")
case True
then show ?thesis using a1 f1 f2 f3
apply (simp add: memory_write_asi_def)
using store_word_mem_privilege add_data_cache_privilege
by blast
next
case False
then have f4: "uint asi ∉ {10,11}" by auto
then show ?thesis
proof (cases "uint asi = 13")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply (simp add: memory_write_asi_def)
by (auto simp add: add_instr_cache_privilege)
next
case False
then have f5: "uint asi ≠ 13" by auto
then show ?thesis
proof (cases "uint asi = 15")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5
apply (simp add: memory_write_asi_def)
by (auto simp add: add_data_cache_privilege)
next
case False
then have f6: "uint asi ≠ 15" by auto
then show ?thesis
proof (cases "uint asi = 16")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
by (auto simp add: flush_instr_cache_privilege)
next
case False
then have f7: "uint asi ≠ 16" by auto
then show ?thesis
proof (cases "uint asi = 17")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
by (auto simp add: flush_data_cache_privilege)
next
case False
then have f8: "uint asi ≠ 17" by auto
then show ?thesis
proof (cases "uint asi = 24")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
by (auto simp add: flush_cache_all_privilege)
next
case False
then have f9: "uint asi ≠ 24" by auto
then show ?thesis
proof (cases "uint asi = 25")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
apply (case_tac "mmu_reg_mod (mmu s) addr data = None")
apply auto
by (simp add: cpu_reg_val_def)
next
case False
then have f10: "uint asi ≠ 25" by auto
then show ?thesis
proof (cases "uint asi = 28")
case True
then show ?thesis using a1
apply (simp add: memory_write_asi_def)
by (auto simp add: mem_mod_w32_privilege)
next
case False
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
apply (simp add: memory_write_asi_def)
apply (auto simp add: Let_def)
apply (case_tac "uint asi = 20 ∨ uint asi = 21")
by auto
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
lemma memory_write_privilege:
assumes a1: "r = memory_write asi addr byte_mask data
(s::(('a::len) sparc_state)) ∧
r = Some s' ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR
(s'::(('a::len) sparc_state)))))::word1) = 0"
proof -
have "∀x. Some x ≠ None" by auto
then have "r ≠ None" using a1
by (simp add: ‹r = memory_write asi addr byte_mask data s ∧
r = Some s' ∧ (get_S (cpu_reg_val PSR s)) = 0›)
then have "∃s''. r = Some (store_barrier_pending_mod False s'')" using a1
by (metis (no_types, lifting) memory_write_def option.case_eq_if)
then have "∃s''. s' = store_barrier_pending_mod False s''" using a1
by blast
then have "∃s''. memory_write_asi asi addr byte_mask data s = Some s'' ∧
s' = store_barrier_pending_mod False s''"
by (metis (no_types, lifting) assms memory_write_def not_None_eq option.case_eq_if option.sel)
then show ?thesis using a1
using memory_write_asi_privilege store_barrier_pending_mod_privilege by blast
qed
lemma store_sub2_privilege:
assumes a1: "s' = snd (fst (store_sub2 instr curr_win rd asi address s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "memory_write asi address (st_byte_mask instr address)
(st_data0 instr curr_win rd address s) s =
None")
case True
then show ?thesis using a1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (metis fst_conv raise_trap_privilege return_def snd_conv)
next
case False
then have f1: "¬(memory_write asi address (st_byte_mask instr address)
(st_data0 instr curr_win rd address s) s =
None)"
by auto
then show ?thesis
proof (cases "(fst instr) ∈ {load_store_type STD,load_store_type STDA}")
case True
then have f2: "(fst instr) ∈ {load_store_type STD,load_store_type STDA}" by auto
then show ?thesis using a1 f1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def)
apply (simp add: bind_def case_prod_unfold)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: case_prod_unfold bind_def h1_def h2_def Let_def simpler_modify_def)
apply (simp add: simpler_gets_def)
apply auto
using memory_write_privilege raise_trap_privilege apply blast
apply (simp add: simpler_modify_def simpler_gets_def bind_def)
apply (meson memory_write_privilege)
using memory_write_privilege raise_trap_privilege apply blast
by (meson memory_write_privilege)
next
case False
then show ?thesis using a1 f1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply clarsimp
apply (simp add: simpler_modify_def return_def)
by (auto intro: memory_write_privilege)
qed
qed
lemma store_sub1_privilege:
assumes a1: "s' = snd (fst (store_sub1 instr rd s_val
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR
(s'::(('a::len) sparc_state)))))::word1) = 0"
proof (cases "(fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s)))))::word1) ≠ 0")
case True
then show ?thesis using a1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
using get_curr_win_privilege raise_trap_privilege by blast
next
case False
then have f1: "¬((fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s)))))::word1) ≠ 0)"
by auto
then show ?thesis
proof (cases "(fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s)))))::word2) ≠ 0")
case True
then show ?thesis using a1 f1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
using get_curr_win_privilege raise_trap_privilege by blast
next
case False
then have f2: "¬((fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s)))))::word2) ≠ 0)"
by auto
then show ?thesis
proof (cases "(fst instr ∈ {load_store_type STD,load_store_type STDA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s)))))::word3) ≠ 0")
case True
then show ?thesis using a1 f1 f2
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
using get_curr_win_privilege raise_trap_privilege by blast
next
case False
then show ?thesis using a1 f1 f2
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson get_curr_win_privilege store_sub2_privilege)
qed
qed
qed
lemma store_instr_privilege:
assumes a1: "s' = snd (fst (store_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR
(s'::(('a::len) sparc_state)))))::word1) = 0"
using a1
apply (simp add: store_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
using raise_trap_privilege store_sub1_privilege by blast
lemma sethi_instr_privilege:
assumes a1: "s' = snd (fst (sethi_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: sethi_instr_def)
apply (simp add: Let_def)
apply auto
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
using get_curr_win_privilege write_reg_privilege apply blast
by (simp add: return_def)
lemma nop_instr_privilege:
assumes a1: "s' = snd (fst (nop_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: nop_instr_def)
by (simp add: return_def)
lemma ucast_0: "(((get_S w))::word1) = 0 ⟹ get_S w = 0"
by simp
lemma ucast_02: "get_S w = 0 ⟹ (((get_S w))::word1) = 0"
by simp
lemma ucast_s: "(((get_S w))::word1) = 0 ⟹
(AND) w (0b00000000000000000000000010000000::word32) = 0"
by (simp add: get_S_def split: if_splits)
lemma ucast_s2: "(AND) w 0b00000000000000000000000010000000 = 0
⟹ (((get_S w))::word1) = 0"
by (simp add: get_S_def)
lemma update_PSR_icc_1: "w' = (AND) w (0b11111111000011111111111111111111::word32)
∧ (((get_S w))::word1) = 0
⟹ (((get_S w'))::word1) = 0"
by (simp add: get_S_def word_bw_assocs(1))
lemma and_num_1048576_128: "(AND) (0b00000000000100000000000000000000::word32)
(0b00000000000000000000000010000000::word32) = 0"
by simp
lemma and_num_2097152_128: "(AND) (0b00000000001000000000000000000000::word32)
(0b00000000000000000000000010000000::word32) = 0"
by simp
lemma and_num_4194304_128: "(AND) (0b00000000010000000000000000000000::word32)
(0b00000000000000000000000010000000::word32) = 0"
by simp
lemma and_num_8388608_128: "(AND) (0b00000000100000000000000000000000::word32)
(0b00000000000000000000000010000000::word32) = 0"
by simp
lemma or_and_s: "(AND) w1 (0b00000000000000000000000010000000::word32) = 0
∧ (AND) w2 (0b00000000000000000000000010000000::word32) = 0
⟹ (AND) ((OR) w1 w2) (0b00000000000000000000000010000000::word32) = 0"
by (simp add: word_ao_dist)
lemma and_or_s:
assumes "(((get_S w1))::word1) = 0 ∧
(AND) w2 (0b00000000000000000000000010000000::word32) = 0"
shows "(((get_S ((OR) ((AND) w1
(0b11111111000011111111111111111111::word32)) w2)))::word1) = 0"
proof -
from assms have "w1 AND 128 = 0"
using ucast_s by blast
then have "(w1 AND 4279238655 OR w2) AND 128 = 0"
using assms by (metis word_ao_absorbs(6) word_ao_dist word_bw_comms(2))
then show ?thesis
using ucast_s2 by blast
qed
lemma and_or_or_s:
assumes a1: "(((get_S w1))::word1) = 0 ∧
(AND) w2 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w3 (0b00000000000000000000000010000000::word32) = 0"
shows "(((get_S ((OR) ((OR) ((AND) w1
(0b11111111000011111111111111111111::word32)) w2) w3)))::word1) = 0"
using and_or_s assms or_and_s ucast_s ucast_s2 by blast
lemma and_or_or_or_s:
assumes a1: "(((get_S w1))::word1) = 0 ∧
(AND) w2 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w3 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w4 (0b00000000000000000000000010000000::word32) = 0"
shows "(((get_S ((OR) ((OR) ((OR) ((AND) w1
(0b11111111000011111111111111111111::word32)) w2) w3) w4)))::word1) = 0"
using and_or_or_s assms or_and_s ucast_s ucast_s2
by (simp add: and_or_or_s assms or_and_s ucast_s ucast_s2)
lemma and_or_or_or_or_s:
assumes a1: "(((get_S w1))::word1) = 0 ∧
(AND) w2 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w3 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w4 (0b00000000000000000000000010000000::word32) = 0 ∧
(AND) w5 (0b00000000000000000000000010000000::word32) = 0"
shows "(((get_S ((OR) ((OR) ((OR) ((OR) ((AND) w1
(0b11111111000011111111111111111111::word32)) w2) w3) w4) w5)))::word1) = 0"
using and_or_or_or_s assms or_and_s ucast_s ucast_s2
by (simp add: and_or_or_or_s assms or_and_s ucast_s ucast_s2)
lemma write_cpu_PSR_icc_privilege:
assumes a1: "s' = snd (fst (write_cpu (update_PSR_icc n_val z_val v_val c_val
(cpu_reg_val PSR s))
PSR
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: write_cpu_def)
apply (simp add: simpler_modify_def)
apply (simp add: cpu_reg_mod_def update_PSR_icc_def)
apply (simp add: cpu_reg_val_def)
apply auto
using update_PSR_icc_1 apply blast
using update_PSR_icc_1 and_num_1048576_128 and_or_s apply blast
using update_PSR_icc_1 and_num_2097152_128 and_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_2097152_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_4194304_128 and_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_4194304_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_2097152_128 and_num_4194304_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_2097152_128 and_num_4194304_128
and_or_or_or_s apply blast
using update_PSR_icc_1 and_num_8388608_128 and_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_8388608_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_2097152_128 and_num_8388608_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_2097152_128 and_num_8388608_128
and_or_or_or_s apply blast
using update_PSR_icc_1 and_num_4194304_128 and_num_8388608_128
and_or_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_4194304_128 and_num_8388608_128
and_or_or_or_s apply blast
using update_PSR_icc_1 and_num_2097152_128 and_num_4194304_128 and_num_8388608_128
and_or_or_or_s apply blast
using update_PSR_icc_1 and_num_1048576_128 and_num_2097152_128 and_num_4194304_128
and_num_8388608_128 and_or_or_or_or_s by blast
lemma and_num_4294967167_128: "(AND) (0b11111111111111111111111101111111::word32)
(0b00000000000000000000000010000000::word32) = 0"
by simp
lemma s_0_word: "(((get_S ((AND) w
(0b11111111111111111111111101111111::word32))))::word1) = 0"
apply (simp add: get_S_def)
using and_num_4294967167_128
by (simp add: ac_simps)
lemma update_PSR_CWP_1: "w' = (AND) w (0b11111111111111111111111111100000::word32)
∧ (((get_S w))::word1) = 0
⟹ (((get_S w'))::word1) = 0"
by (simp add: get_S_def word_bw_assocs(1))
lemma write_cpu_PSR_CWP_privilege:
assumes a1: "s' = snd (fst (write_cpu (update_CWP cwp_val
(cpu_reg_val PSR s))
PSR
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: write_cpu_def)
apply (simp add: simpler_modify_def)
apply (simp add: cpu_reg_mod_def)
apply (simp add: update_CWP_def)
apply (simp add: Let_def)
apply auto
apply (simp add: cpu_reg_val_def)
using s_0_word by blast
lemma logical_instr_sub1_privilege:
assumes a1: "s' = snd (fst (logical_instr_sub1 instr_name result
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "instr_name = logic_type ANDcc ∨
instr_name = logic_type ANDNcc ∨
instr_name = logic_type ORcc ∨
instr_name = logic_type ORNcc ∨
instr_name = logic_type XORcc ∨ instr_name = logic_type XNORcc")
case True
then show ?thesis using a1
apply (simp add: logical_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: logical_new_psr_val_def)
using write_cpu_PSR_icc_privilege by blast
next
case False
then show ?thesis using a1
apply (simp add: logical_instr_sub1_def)
by (simp add: return_def)
qed
lemma logical_instr_privilege:
assumes a1: "s' = snd (fst (logical_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: logical_instr_def)
apply (simp add: Let_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply auto
apply (meson get_curr_win_privilege logical_instr_sub1_privilege write_reg_privilege)
by (meson get_curr_win_privilege logical_instr_sub1_privilege write_reg_privilege)
method shift_instr_privilege_proof = (
(simp add: shift_instr_def),
(simp add: Let_def),
(simp add: simpler_gets_def),
(simp add: bind_def h1_def h2_def Let_def case_prod_unfold),
auto,
(blast intro: get_curr_win_privilege write_reg_privilege),
(blast intro: get_curr_win_privilege write_reg_privilege)
)
lemma shift_instr_privilege:
assumes a1: "s' = snd (fst (shift_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "(fst instr = shift_type SLL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1
by shift_instr_privilege_proof
next
case False
then have f1: "¬((fst instr = shift_type SLL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0))"
by auto
then show ?thesis
proof (cases "(fst instr = shift_type SRL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1 f1
by shift_instr_privilege_proof
next
case False
then have f2: "¬((fst instr = shift_type SRL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0))"
by auto
then show ?thesis
proof (cases "(fst instr = shift_type SRA) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1 f1 f2
by shift_instr_privilege_proof
next
case False
then show ?thesis using a1 f1 f2
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def case_prod_unfold)
apply (simp add: return_def)
using get_curr_win_privilege by blast
qed
qed
qed
lemma add_instr_sub1_privilege:
assumes a1: "s' = snd (fst (add_instr_sub1 instr_name result rs1_val operand2
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "instr_name = arith_type ADDcc ∨ instr_name = arith_type ADDXcc")
case True
then show ?thesis using a1
apply (simp add: add_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: write_cpu_PSR_icc_privilege)
next
case False
then show ?thesis using a1
apply (simp add: add_instr_sub1_def)
by (simp add: return_def)
qed
lemma add_instr_privilege:
assumes a1: "s' = snd (fst (add_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: add_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson add_instr_sub1_privilege get_curr_win_privilege write_reg_privilege)
lemma sub_instr_sub1_privilege:
assumes a1: "s' = snd (fst (sub_instr_sub1 instr_name result rs1_val operand2
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "instr_name = arith_type SUBcc ∨ instr_name = arith_type SUBXcc")
case True
then show ?thesis using a1
apply (simp add: sub_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: write_cpu_PSR_icc_privilege)
next
case False
then show ?thesis using a1
apply (simp add: sub_instr_sub1_def)
by (simp add: return_def)
qed
lemma sub_instr_privilege:
assumes a1: "s' = snd (fst (sub_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: sub_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson sub_instr_sub1_privilege get_curr_win_privilege write_reg_privilege)
lemma mul_instr_sub1_privilege:
assumes a1: "s' = snd (fst (mul_instr_sub1 instr_name result
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "instr_name ∈ {arith_type SMULcc,arith_type UMULcc}")
case True
then show ?thesis using a1
apply (simp add: mul_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: write_cpu_PSR_icc_privilege)
next
case False
then show ?thesis using a1
apply (simp add: mul_instr_sub1_def)
by (simp add: return_def)
qed
lemma mul_instr_privilege:
assumes a1: "s' = snd (fst (mul_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: mul_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson get_curr_win_privilege mul_instr_sub1_privilege write_cpu_y_privilege write_reg_privilege)
lemma div_write_new_val_privilege:
assumes a1: "s' = snd (fst (div_write_new_val i result temp_V
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "(fst i) ∈ {arith_type UDIVcc,arith_type SDIVcc}")
case True
then show ?thesis using a1
apply (simp add: div_write_new_val_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: write_cpu_PSR_icc_privilege)
next
case False
then show ?thesis using a1
apply (simp add: div_write_new_val_def)
by (simp add: return_def)
qed
lemma div_comp_privilege:
assumes a1: "s' = snd (fst (div_comp instr rs1 rd operand2
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: div_comp_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson get_curr_win_privilege div_write_new_val_privilege write_reg_privilege)
lemma div_instr_privilege:
assumes a1: "s' = snd (fst (div_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: div_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: return_def)
apply auto
using raise_trap_privilege apply blast
using div_comp_privilege by blast
lemma save_retore_sub1_privilege:
assumes a1: "s' = snd (fst (save_retore_sub1 result new_cwp rd
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: save_retore_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
using write_cpu_PSR_CWP_privilege write_reg_privilege by blast
method save_restore_instr_privilege_proof = (
(simp add: save_restore_instr_def),
(simp add: Let_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def),
(simp add: case_prod_unfold),
auto,
(blast intro: get_curr_win_privilege raise_trap_privilege),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def case_prod_unfold),
(blast intro: get_curr_win_privilege save_retore_sub1_privilege)
)
lemma save_restore_instr_privilege:
assumes a1: "s' = snd (fst (save_restore_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "fst instr = ctrl_type SAVE")
case True
then have f1: "fst instr = ctrl_type SAVE" by auto
then show ?thesis using a1
by save_restore_instr_privilege_proof
next
case False
then show ?thesis using a1
by save_restore_instr_privilege_proof
qed
lemma call_instr_privilege:
assumes a1: "s' = snd (fst (call_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: call_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson get_curr_win_privilege write_cpu_npc_privilege write_cpu_pc_privilege write_reg_privilege)
lemma jmpl_instr_privilege:
assumes a1: "s' = snd (fst (jmpl_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: jmpl_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
using get_curr_win_privilege raise_trap_privilege apply blast
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (meson get_curr_win_privilege write_cpu_npc_privilege write_cpu_pc_privilege write_reg_privilege)
lemma rett_instr_privilege:
assumes a1: "snd (rett_instr i s) = False ∧
s' = snd (fst (rett_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: rett_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply auto
apply (simp add: case_prod_unfold)
apply (simp add: return_def)
apply (blast intro: raise_trap_privilege)
apply (simp add: bind_def h1_def h2_def Let_def)
by (simp add: case_prod_unfold fail_def)
method read_state_reg_instr_privilege_proof = (
(simp add: read_state_reg_instr_def),
(simp add: Let_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def),
(simp add: case_prod_unfold)
)
lemma read_state_reg_instr_privilege:
assumes a1: "s' = snd (fst (read_state_reg_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "(fst instr ∈ {sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR} ∨
(fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 ((snd instr)!0))))")
case True
then have "(fst instr ∈ {sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR} ∨
(fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 ((snd instr)!0))))
∧ (((get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s))))))::word1) = 0"
by (metis assms get_curr_win_privilege)
then show ?thesis using a1
apply read_state_reg_instr_privilege_proof
by (blast intro: raise_trap_privilege get_curr_win_privilege)
next
case False
then have f1: "¬((fst instr = sreg_type RDPSR ∨
fst instr = sreg_type RDWIM ∨
fst instr = sreg_type RDTBR ∨
fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 (snd instr ! 0))) ∧
(get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s))))) = 0)"
by blast
then show ?thesis
proof (cases "illegal_instruction_ASR (get_operand_w5 ((snd instr)!0))")
case True
then show ?thesis using a1 f1
apply read_state_reg_instr_privilege_proof
by (simp add: illegal_instruction_ASR_def)
next
case False
then have f2: "¬(illegal_instruction_ASR (get_operand_w5 ((snd instr)!0)))"
by auto
then show ?thesis
proof (cases "(get_operand_w5 ((snd instr)!1)) ≠ 0")
case True
then have f3: "(get_operand_w5 ((snd instr)!1)) ≠ 0"
by auto
then show ?thesis
proof (cases "fst instr = sreg_type RDY")
case True
then show ?thesis using a1 f1 f2 f3
apply (simp add: read_state_reg_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (blast intro: get_curr_win_privilege write_reg_privilege)
next
case False
then have f4: "¬(fst instr = sreg_type RDY)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type RDASR")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply read_state_reg_instr_privilege_proof
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: get_curr_win_privilege write_reg_privilege)
next
case False
then have f5: "¬(fst instr = sreg_type RDASR)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type RDPSR")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5
apply read_state_reg_instr_privilege_proof
by (blast intro: get_curr_win_privilege write_reg_privilege)
next
case False
then show ?thesis using a1 f1 f2 f3 f4 f5
apply read_state_reg_instr_privilege_proof
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (blast intro: get_curr_win_privilege write_reg_privilege)
qed
qed
qed
next
case False
then show ?thesis using a1
apply read_state_reg_instr_privilege_proof
apply (simp add: return_def)
using f1 f2 get_curr_win_privilege by blast
qed
qed
qed
method write_state_reg_instr_privilege_proof = (
(simp add: write_state_reg_instr_def),
(simp add: Let_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def),
(simp add: case_prod_unfold)
)
lemma write_state_reg_instr_privilege:
assumes a1: "s' = snd (fst (write_state_reg_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "fst instr = sreg_type WRY")
case True
then show ?thesis using a1
apply write_state_reg_instr_privilege_proof
apply (simp add: simpler_modify_def)
apply (simp add: delayed_pool_add_def DELAYNUM_def)
by (blast intro: cpu_reg_mod_y_privilege get_curr_win_privilege)
next
case False
then have f1: "¬(fst instr = sreg_type WRY)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type WRASR")
case True
then show ?thesis
using a1 f1
apply write_state_reg_instr_privilege_proof
apply (simp add: simpler_modify_def)
apply auto
using illegal_instruction_ASR_def apply blast
using illegal_instruction_ASR_def apply blast
using illegal_instruction_ASR_def apply blast
using raise_trap_privilege get_curr_win_privilege apply blast
apply (simp add: simpler_modify_def delayed_pool_add_def DELAYNUM_def)
using cpu_reg_mod_asr_privilege get_curr_win_privilege apply blast
apply (simp add: simpler_modify_def delayed_pool_add_def DELAYNUM_def)
using cpu_reg_mod_asr_privilege get_curr_win_privilege by blast
next
case False
then have f2: "¬(fst instr = sreg_type WRASR)" by auto
have f3: "get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s)))) = 0"
using get_curr_win_privilege a1 by (metis ucast_id)
then show ?thesis
proof (cases "fst instr = sreg_type WRPSR")
case True
then show ?thesis using a1 f1 f2 f3
apply write_state_reg_instr_privilege_proof
by (metis raise_trap_privilege ucast_0)
next
case False
then have f4: "¬(fst instr = sreg_type WRPSR)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type WRWIM")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply write_state_reg_instr_privilege_proof
by (metis raise_trap_privilege ucast_0)
next
case False
then have f5: "¬(fst instr = sreg_type WRWIM)" by auto
then show ?thesis using a1 f1 f2 f3 f4 f5
apply write_state_reg_instr_privilege_proof
by (metis raise_trap_privilege ucast_0)
qed
qed
qed
qed
lemma flush_instr_privilege:
assumes a1: "s' = snd (fst (flush_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: flush_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def simpler_modify_def)
by (auto simp add: flush_cache_all_privilege)
lemma branch_instr_privilege:
assumes a1: "s' = snd (fst (branch_instr instr
(s::(('a::len) sparc_state))))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
using a1
apply (simp add: branch_instr_def)
apply (simp add: Let_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold return_def)
by (meson set_annul_privilege write_cpu_npc_privilege write_cpu_pc_privilege)
method dispath_instr_privilege_proof = (
(simp add: dispatch_instruction_def),
(simp add: simpler_gets_def bind_def h1_def h2_def Let_def),
(simp add: Let_def)
)
lemma dispath_instr_privilege:
assumes a1: "snd (dispatch_instruction instr s) = False ∧
s' = snd (fst (dispatch_instruction instr s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "get_trap_set s = {}")
case True
then have f1: "get_trap_set s = {}" by auto
show ?thesis
proof (cases "fst instr ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD}")
case True
then show ?thesis using a1 f1
apply dispath_instr_privilege_proof
by (blast intro: load_instr_privilege)
next
case False
then have f2: "¬(fst instr ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD}")
case True
then show ?thesis using a1 f1 f2
apply dispath_instr_privilege_proof
by (blast intro: store_instr_privilege)
next
case False
then have f3: "¬(fst instr ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {sethi_type SETHI}")
case True
then show ?thesis using a1 f1 f2 f3
apply dispath_instr_privilege_proof
by (blast intro: sethi_instr_privilege)
next
case False
then have f4: "¬(fst instr ∈ {sethi_type SETHI})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {nop_type NOP}")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply dispath_instr_privilege_proof
by (blast intro: nop_instr_privilege)
next
case False
then have f5: "¬(fst instr ∈ {nop_type NOP})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {logic_type ANDs,logic_type ANDcc,logic_type ANDN,
logic_type ANDNcc,logic_type ORs,logic_type ORcc,logic_type ORN,
logic_type XORs,logic_type XNOR}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5
apply dispath_instr_privilege_proof
by (blast intro: logical_instr_privilege)
next
case False
then have f6: "¬(fst instr ∈ {logic_type ANDs,logic_type ANDcc,logic_type ANDN,
logic_type ANDNcc,logic_type ORs,logic_type ORcc,logic_type ORN,
logic_type XORs,logic_type XNOR})"
by auto
show ?thesis
proof (cases "fst instr ∈ {shift_type SLL,shift_type SRL,shift_type SRA}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6
apply dispath_instr_privilege_proof
by (blast intro: shift_instr_privilege)
next
case False
then have f7: "¬(fst instr ∈ {shift_type SLL,shift_type SRL,shift_type SRA})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type ADD,arith_type ADDcc,arith_type ADDX}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7
apply dispath_instr_privilege_proof
by (blast intro: add_instr_privilege)
next
case False
then have f8: "¬(fst instr ∈ {arith_type ADD,arith_type ADDcc,arith_type ADDX})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type SUB,arith_type SUBcc,arith_type SUBX}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8
apply dispath_instr_privilege_proof
by (blast intro: sub_instr_privilege)
next
case False
then have f9: "¬(fst instr ∈ {arith_type SUB,arith_type SUBcc,arith_type SUBX})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type UMUL,arith_type SMUL,arith_type SMULcc}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9
apply dispath_instr_privilege_proof
by (blast intro: mul_instr_privilege)
next
case False
then have f10: "¬(fst instr ∈ {arith_type UMUL,arith_type SMUL,
arith_type SMULcc})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type UDIV,arith_type UDIVcc,arith_type SDIV}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
apply dispath_instr_privilege_proof
by (blast intro: div_instr_privilege)
next
case False
then have f11: "¬(fst instr ∈ {arith_type UDIV,
arith_type UDIVcc,arith_type SDIV})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type SAVE,ctrl_type RESTORE}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
apply dispath_instr_privilege_proof
by (blast intro: save_restore_instr_privilege)
next
case False
then have f12: "¬(fst instr ∈ {ctrl_type SAVE,ctrl_type RESTORE})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {call_type CALL}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
apply dispath_instr_privilege_proof
by (blast intro: call_instr_privilege)
next
case False
then have f13: "¬(fst instr ∈ {call_type CALL})" by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type JMPL}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
apply dispath_instr_privilege_proof
by (blast intro: jmpl_instr_privilege)
next
case False
then have f14: "¬(fst instr ∈ {ctrl_type JMPL})" by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type RETT}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13
f14
apply dispath_instr_privilege_proof
by (blast intro: rett_instr_privilege)
next
case False
then have f15: "¬(fst instr ∈ {ctrl_type RETT})" by auto
then show ?thesis
proof (cases "fst instr ∈ {sreg_type RDY,sreg_type RDPSR,
sreg_type RDWIM, sreg_type RDTBR}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15
apply dispath_instr_privilege_proof
by (blast intro: read_state_reg_instr_privilege)
next
case False
then have f16: "¬(fst instr ∈ {sreg_type RDY,sreg_type RDPSR,
sreg_type RDWIM, sreg_type RDTBR})" by auto
then show ?thesis
proof (cases "fst instr ∈ {sreg_type WRY,sreg_type WRPSR,
sreg_type WRWIM, sreg_type WRTBR}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
f13 f14 f15 f16
apply dispath_instr_privilege_proof
by (blast intro: write_state_reg_instr_privilege)
next
case False
then have f17: "¬(fst instr ∈ {sreg_type WRY,sreg_type WRPSR,
sreg_type WRWIM, sreg_type WRTBR})" by auto
then show ?thesis
proof (cases "fst instr ∈ {load_store_type FLUSH}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17
apply dispath_instr_privilege_proof
by (blast intro: flush_instr_privilege)
next
case False
then have f18: "¬(fst instr ∈ {load_store_type FLUSH})" by auto
then show ?thesis
proof (cases "fst instr ∈ {bicc_type BE,bicc_type BNE,
bicc_type BGU,bicc_type BLE,bicc_type BL,bicc_type BGE,
bicc_type BNEG,bicc_type BG,bicc_type BCS,bicc_type BLEU,
bicc_type BCC,bicc_type BA,bicc_type BN}")
case True
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18
apply dispath_instr_privilege_proof
by (blast intro: branch_instr_privilege)
next
case False
then show ?thesis using a1 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
f12 f13 f14 f15 f16 f17 f18
apply dispath_instr_privilege_proof
by (simp add: fail_def)
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
next
case False
then show ?thesis using a1
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
by (simp add: return_def)
qed
lemma execute_instr_sub1_privilege:
assumes a1: "snd (execute_instr_sub1 i s) = False ∧
s' = snd (fst (execute_instr_sub1 i s))
∧ (((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "get_trap_set s = {} ∧ fst i ∉ {call_type CALL,ctrl_type RETT,ctrl_type JMPL,
bicc_type BE,bicc_type BNE,bicc_type BGU,
bicc_type BLE,bicc_type BL,bicc_type BGE,
bicc_type BNEG,bicc_type BG,
bicc_type BCS,bicc_type BLEU,bicc_type BCC,
bicc_type BA,bicc_type BN}")
case True
then show ?thesis using a1
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold return_def)
by (auto intro: write_cpu_pc_privilege write_cpu_npc_privilege)
next
case False
then show ?thesis using a1
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold return_def)
by auto
qed
text ‹
Assume that there is no ‹delayed_write› and
there is no traps to be executed.
If an instruction is executed as a user,
the privilege will not be changed to supervisor after
the execution.›
theorem safe_privilege :
assumes a1: "get_delayed_pool s = [] ∧ get_trap_set s = {} ∧
snd (execute_instruction() s) = False ∧
s' = snd (fst (execute_instruction() s)) ∧
(((get_S (cpu_reg_val PSR s)))::word1) = 0"
shows "(((get_S (cpu_reg_val PSR s')))::word1) = 0"
proof (cases "exe_mode_val s")
case True
then have f2: "exe_mode_val s = True" by auto
then show ?thesis
proof (cases "∃e. fetch_instruction (delayed_pool_write s) = Inl e")
case True
then have f3: "∃e. fetch_instruction (delayed_pool_write s) = Inl e"
by auto
then have f4: "¬ (∃v. fetch_instruction (delayed_pool_write s) = Inr v)"
using fetch_instr_result_3 by auto
then show ?thesis using a1 f2 f3 raise_trap_result empty_delayed_pool_write_privilege raise_trap_privilege
apply (simp add: execute_instruction_def)
apply (simp add: exec_gets return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: case_prod_unfold)
by (blast intro: empty_delayed_pool_write_privilege raise_trap_privilege)
next
case False
then have f5: "∃v. fetch_instruction (delayed_pool_write s) = Inr v"
using fetch_instr_result_1 by blast
then have f6: "∃v. fetch_instruction (delayed_pool_write s) = Inr v ∧
¬ (∃e. ((decode_instruction v)::(Exception list + instruction)) = Inl e)"
using a1 f2 dispatch_fail by blast
then have f7: "∃v. fetch_instruction (delayed_pool_write s) = Inr v ∧
(∃v1. ((decode_instruction v)::(Exception list + instruction)) = Inr v1)"
using decode_instr_result_4 by auto
then show ?thesis
proof (cases "annul_val (delayed_pool_write s)")
case True
then show ?thesis using a1 f2 f7
apply (simp add: execute_instruction_def)
apply (simp add: exec_gets return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (auto intro: empty_delayed_pool_write_privilege
set_annul_privilege write_cpu_npc_privilege write_cpu_pc_privilege)
next
case False
then show ?thesis using a1 f2 f7
apply (simp add: execute_instruction_def)
apply (simp add: exec_gets return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
by (auto intro: empty_delayed_pool_write_privilege dispath_instr_privilege
execute_instr_sub1_privilege)
qed
qed
next
case False
then show ?thesis using a1
apply (simp add: execute_instruction_def)
by (simp add: simpler_gets_def bind_def h1_def h2_def Let_def return_def)
qed
section ‹Single step non-interference property.›
definition user_accessible:: "('a::len) sparc_state ⇒ phys_address ⇒ bool" where
"user_accessible s pa ≡ ∃va p. (virt_to_phys va (mmu s) (mem s)) = Some p ∧
mmu_readable (get_acc_flag (snd p)) 10 ∧
(fst p) = pa"
lemma user_accessible_8:
assumes a1: "mmu_readable (get_acc_flag (snd p)) 8"
shows "mmu_readable (get_acc_flag (snd p)) 10"
using a1 by (simp add: mmu_readable_def)
definition mem_equal:: "('a) sparc_state ⇒ ('a) sparc_state ⇒
phys_address ⇒ bool" where
"mem_equal s1 s2 pa ≡
(mem s1) 8 (pa AND 68719476732) = (mem s2) 8 (pa AND 68719476732) ∧
(mem s1) 8 ((pa AND 68719476732) + 1) = (mem s2) 8 ((pa AND 68719476732) + 1) ∧
(mem s1) 8 ((pa AND 68719476732) + 2) = (mem s2) 8 ((pa AND 68719476732) + 2) ∧
(mem s1) 8 ((pa AND 68719476732) + 3) = (mem s2) 8 ((pa AND 68719476732) + 3) ∧
(mem s1) 9 (pa AND 68719476732) = (mem s2) 9 (pa AND 68719476732) ∧
(mem s1) 9 ((pa AND 68719476732) + 1) = (mem s2) 9 ((pa AND 68719476732) + 1) ∧
(mem s1) 9 ((pa AND 68719476732) + 2) = (mem s2) 9 ((pa AND 68719476732) + 2) ∧
(mem s1) 9 ((pa AND 68719476732) + 3) = (mem s2) 9 ((pa AND 68719476732) + 3) ∧
(mem s1) 10 (pa AND 68719476732) = (mem s2) 10 (pa AND 68719476732) ∧
(mem s1) 10 ((pa AND 68719476732) + 1) = (mem s2) 10 ((pa AND 68719476732) + 1) ∧
(mem s1) 10 ((pa AND 68719476732) + 2) = (mem s2) 10 ((pa AND 68719476732) + 2) ∧
(mem s1) 10 ((pa AND 68719476732) + 3) = (mem s2) 10 ((pa AND 68719476732) + 3) ∧
(mem s1) 11 (pa AND 68719476732) = (mem s2) 11 (pa AND 68719476732) ∧
(mem s1) 11 ((pa AND 68719476732) + 1) = (mem s2) 11 ((pa AND 68719476732) + 1) ∧
(mem s1) 11 ((pa AND 68719476732) + 2) = (mem s2) 11 ((pa AND 68719476732) + 2) ∧
(mem s1) 11 ((pa AND 68719476732) + 3) = (mem s2) 11 ((pa AND 68719476732) + 3)"
text ‹‹low_equal› defines the equivalence relation over two sparc
states that is an analogy to the ‹=⇩L› relation over memory contexts
in the traditional non-interference theorem.›
definition low_equal:: "('a::len) sparc_state ⇒ ('a) sparc_state ⇒ bool" where
"low_equal s1 s2 ≡
(cpu_reg s1) = (cpu_reg s2) ∧
(user_reg s1) = (user_reg s2) ∧
(sys_reg s1) = (sys_reg s2) ∧
(∀va. (virt_to_phys va (mmu s1) (mem s1)) = (virt_to_phys va (mmu s2) (mem s2))) ∧
(∀pa. (user_accessible s1 pa) ⟶ mem_equal s1 s2 pa) ∧
(mmu s1) = (mmu s2) ∧
(state_var s1) = (state_var s2) ∧
(traps s1) = (traps s2) ∧
(undef s1) = (undef s2)
"
lemma low_equal_com: "low_equal s1 s2 ⟹ low_equal s2 s1"
apply (simp add: low_equal_def)
apply (simp add: mem_equal_def user_accessible_def)
by metis
lemma non_exe_mode_equal: "exe_mode_val s = False ∧
get_trap_set s = {} ∧
Some t = NEXT s ⟹
t = s"
apply (simp add: NEXT_def execute_instruction_def)
apply auto
by (simp add: simpler_gets_def bind_def h1_def h2_def Let_def return_def)
lemma exe_mode_low_equal:
assumes a1: "low_equal s1 s2"
shows " exe_mode_val s1 = exe_mode_val s2"
using a1 apply (simp add: low_equal_def)
by (simp add: exe_mode_val_def)
lemma mem_val_mod_state: "mem_val_alt asi a s = mem_val_alt asi a
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈)"
apply (simp add: mem_val_alt_def)
by (simp add: Let_def)
lemma mem_val_w32_mod_state: "mem_val_w32 asi a s = mem_val_w32 asi a
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈)"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
by (metis mem_val_mod_state)
lemma load_word_mem_mod_state: "load_word_mem s addr asi = load_word_mem
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi"
apply (simp add: load_word_mem_def)
apply (case_tac "virt_to_phys addr (mmu s) (mem s) = None")
apply auto
by (auto simp add: mem_val_w32_mod_state)
lemma load_word_mem2_mod_state:
"fst (case load_word_mem s addr asi of None ⇒ (None, s)
| Some w ⇒ (Some w, add_data_cache s addr w 15)) =
fst (case load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi of
None ⇒ (None, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈))
| Some w ⇒ (Some w, add_data_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr w 15))"
proof (cases "load_word_mem s addr asi = None")
case True
then have "load_word_mem s addr asi = None ∧
load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi = None"
using load_word_mem_mod_state by metis
then show ?thesis by auto
next
case False
then have "∃w. load_word_mem s addr asi = Some w" by auto
then have "∃w. load_word_mem s addr asi = Some w ∧
load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi = Some w"
using load_word_mem_mod_state by metis
then show ?thesis by auto
qed
lemma load_word_mem3_mod_state:
"fst (case load_word_mem s addr asi of None ⇒ (None, s)
| Some w ⇒ (Some w, add_instr_cache s addr w 15)) =
fst (case load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi of
None ⇒ (None, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈))
| Some w ⇒ (Some w, add_instr_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr w 15))"
proof (cases "load_word_mem s addr asi = None")
case True
then have "load_word_mem s addr asi = None ∧
load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi = None"
using load_word_mem_mod_state by metis
then show ?thesis by auto
next
case False
then have "∃w. load_word_mem s addr asi = Some w" by auto
then have "∃w. load_word_mem s addr asi = Some w ∧
load_word_mem (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr asi = Some w"
using load_word_mem_mod_state by metis
then show ?thesis by auto
qed
lemma read_dcache_mod_state: "read_data_cache s addr = read_data_cache
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr"
apply (simp add: read_data_cache_def)
by (simp add: dcache_val_def)
lemma read_dcache2_mod_state:
"fst (case read_data_cache s addr of None ⇒ (None, s)
| Some w ⇒ (Some w, s)) =
fst (case read_data_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr of
None ⇒ (None, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈))
| Some w ⇒ (Some w, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈)))"
proof (cases "read_data_cache s addr = None")
case True
then have "read_data_cache s addr = None ∧
read_data_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr = None"
using read_dcache_mod_state by metis
then show ?thesis by auto
next
case False
then have "∃w. read_data_cache s addr = Some w" by auto
then have "∃w. read_data_cache s addr = Some w ∧
read_data_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr = Some w"
using read_dcache_mod_state by metis
then show ?thesis by auto
qed
lemma read_icache_mod_state: "read_instr_cache s addr = read_instr_cache
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr"
apply (simp add: read_instr_cache_def)
by (simp add: icache_val_def)
lemma read_icache2_mod_state:
"fst (case read_instr_cache s addr of None ⇒ (None, s)
| Some w ⇒ (Some w, s)) =
fst (case read_instr_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr of
None ⇒ (None, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈))
| Some w ⇒ (Some w, (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈)))"
proof (cases "read_instr_cache s addr = None")
case True
then have "read_instr_cache s addr = None ∧
read_instr_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr = None"
using read_icache_mod_state by metis
then show ?thesis by auto
next
case False
then have "∃w. read_instr_cache s addr = Some w" by auto
then have "∃w. read_instr_cache s addr = Some w ∧
read_instr_cache (s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) addr = Some w"
using read_icache_mod_state by metis
then show ?thesis by auto
qed
lemma mem_read_mod_state: "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈))"
apply (simp add: memory_read_def)
apply (case_tac "uint asi = 1")
apply (simp add: Let_def)
apply (metis load_word_mem_mod_state option.distinct(1))
apply (case_tac "uint asi = 2")
apply (simp add: Let_def)
apply (simp add: sys_reg_val_def)
apply (case_tac "uint asi ∈ {8,9}")
apply (simp add: Let_def)
apply (simp add: load_word_mem3_mod_state)
apply (simp add: load_word_mem_mod_state)
apply (case_tac "uint asi ∈ {10,11}")
apply (simp add: Let_def)
apply (simp add: load_word_mem2_mod_state)
apply (simp add: load_word_mem_mod_state)
apply (case_tac "uint asi = 13")
apply (simp add: Let_def)
apply (simp add: read_icache2_mod_state)
apply (case_tac "uint asi = 15")
apply (simp add: Let_def)
apply (simp add: read_dcache2_mod_state)
apply (case_tac "uint asi = 25")
apply (simp add: Let_def)
apply (case_tac "uint asi = 28")
apply (simp add: Let_def)
apply (simp add: mem_val_w32_mod_state)
by (simp add: Let_def)
lemma insert_trap_mem: "fst (memory_read asi addr s) =
fst (memory_read asi addr (s⦇traps := new_traps⦈))"
proof -
have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := (cpu_reg s),
user_reg := (user_reg s),
dwrite := (dwrite s),
state_var := (state_var s),
traps := new_traps,
undef := (undef s)⦈))"
using mem_read_mod_state by blast
then show ?thesis by auto
qed
lemma cpu_reg_mod_mem: "fst (memory_read asi addr s) =
fst (memory_read asi addr (s⦇cpu_reg := new_cpu_reg⦈))"
proof -
have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := new_cpu_reg,
user_reg := (user_reg s),
dwrite := (dwrite s),
state_var := (state_var s),
traps := (traps s),
undef := (undef s)⦈))"
using mem_read_mod_state by blast
then show ?thesis by auto
qed
lemma user_reg_mod_mem: "fst (memory_read asi addr s) =
fst (memory_read asi addr (s⦇user_reg := new_user_reg⦈))"
proof -
have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := (cpu_reg s),
user_reg := new_user_reg,
dwrite := (dwrite s),
state_var := (state_var s),
traps := (traps s),
undef := (undef s)⦈))"
using mem_read_mod_state by blast
then show ?thesis by auto
qed
lemma annul_mem: "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇state_var := new_state_var,
cpu_reg := new_cpu_reg⦈))"
proof -
have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := new_cpu_reg,
user_reg := (user_reg s),
dwrite := (dwrite s),
state_var := new_state_var,
traps := (traps s),
undef := (undef s)⦈))"
using mem_read_mod_state by blast
then have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := new_cpu_reg,
state_var := new_state_var⦈))"
by auto
then show ?thesis
by (metis Sparc_State.sparc_state.surjective Sparc_State.sparc_state.update_convs(1) Sparc_State.sparc_state.update_convs(8))
qed
lemma state_var_mod_mem: "fst (memory_read asi addr s) =
fst (memory_read asi addr (s⦇state_var := new_state_var⦈))"
proof -
have "fst (memory_read asi addr s) =
fst (memory_read asi addr
(s⦇cpu_reg := (cpu_reg s),
user_reg := (user_reg s),
dwrite := (dwrite s),
state_var := new_state_var,
traps := (traps s),
undef := (undef s)⦈))"
using mem_read_mod_state by blast
then show ?thesis by auto
qed
lemma mod_state_low_equal: "low_equal s1 s2 ∧
t1 = (s1⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) ∧
t2 = (s2⦇cpu_reg := new_cpu_reg,
user_reg := new_user_reg,
dwrite := new_dwrite,
state_var := new_state_var,
traps := new_traps,
undef := new_undef⦈) ⟹
low_equal t1 t2"
apply (simp add: low_equal_def)
apply clarsimp
apply (simp add: mem_equal_def)
by (simp add: user_accessible_def)
lemma user_reg_state_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (s1⦇user_reg := new_user_reg⦈) ∧
t2 = (s2⦇user_reg := new_user_reg⦈)"
shows "low_equal t1 t2"
proof -
have "low_equal s1 s2 ∧
t1 = (s1⦇cpu_reg := (cpu_reg s1),
user_reg := new_user_reg,
dwrite := (dwrite s1),
state_var := (state_var s1),
traps := (traps s1),
undef := (undef s1)⦈) ∧
t2 = (s2⦇cpu_reg := (cpu_reg s2),
user_reg := new_user_reg,
dwrite := (dwrite s2),
state_var := (state_var s2),
traps := (traps s2),
undef := (undef s2)⦈) ⟹
low_equal t1 t2"
using mod_state_low_equal apply (simp add: low_equal_def)
apply (simp add: user_accessible_def mem_equal_def)
by clarsimp
then show ?thesis using a1
by clarsimp
qed
lemma mod_trap_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (s1⦇traps := new_traps⦈) ∧
t2 = (s2⦇traps := new_traps⦈)"
shows "low_equal t1 t2"
proof -
have "low_equal s1 s2 ∧
t1 = (s1⦇cpu_reg := (cpu_reg s1),
user_reg := (user_reg s1),
dwrite := (dwrite s1),
state_var := (state_var s1),
traps := new_traps,
undef := (undef s1)⦈) ∧
t2 = (s2⦇cpu_reg := (cpu_reg s2),
user_reg := (user_reg s2),
dwrite := (dwrite s2),
state_var := (state_var s2),
traps := new_traps,
undef := (undef s2)⦈) ⟹
low_equal t1 t2"
using mod_state_low_equal apply (simp add: low_equal_def)
apply (simp add: user_accessible_def mem_equal_def)
by clarsimp
then show ?thesis using a1
by clarsimp
qed
lemma state_var_low_equal: "low_equal s1 s2 ⟹
state_var s1 = state_var s2"
by (simp add: low_equal_def)
lemma state_var2_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (s1⦇state_var := new_state_var⦈) ∧
t2 = (s2⦇state_var := new_state_var⦈)"
shows "low_equal t1 t2"
proof -
have "low_equal s1 s2 ∧
t1 = (s1⦇cpu_reg := (cpu_reg s1),
user_reg := (user_reg s1),
dwrite := (dwrite s1),
state_var := new_state_var,
traps := (traps s1),
undef := (undef s1)⦈) ∧
t2 = (s2⦇cpu_reg := (cpu_reg s2),
user_reg := (user_reg s2),
dwrite := (dwrite s2),
state_var := new_state_var,
traps := (traps s2),
undef := (undef s2)⦈) ⟹
low_equal t1 t2"
using mod_state_low_equal apply (simp add: low_equal_def)
apply (simp add: user_accessible_def mem_equal_def)
by clarsimp
then show ?thesis using a1
by clarsimp
qed
lemma traps_low_equal: "low_equal s1 s2 ⟹ traps s1 = traps s2"
by (simp add: low_equal_def)
lemma s_low_equal: "low_equal s1 s2 ⟹
(get_S (cpu_reg_val PSR s1)) = (get_S (cpu_reg_val PSR s2))"
by (simp add: low_equal_def cpu_reg_val_def)
lemma cpu_reg_val_low_equal: "low_equal s1 s2 ⟹
(cpu_reg_val cr s1) = (cpu_reg_val cr s2)"
by (simp add: cpu_reg_val_def low_equal_def)
lemma get_curr_win_low_equal: "low_equal s1 s2 ⟹
(fst (fst (get_curr_win () s1))) = (fst (fst (get_curr_win () s2)))"
apply (simp add: low_equal_def)
apply (simp add: get_curr_win_def cpu_reg_val_def get_CWP_def)
by (simp add: simpler_gets_def)
lemma get_curr_win2_low_equal: "low_equal s1 s2 ⟹
t1 = (snd (fst (get_curr_win () s1))) ⟹
t2 = (snd (fst (get_curr_win () s2))) ⟹
low_equal t1 t2"
apply (simp add: low_equal_def)
apply (simp add: get_curr_win_def cpu_reg_val_def get_CWP_def)
by (auto simp add: simpler_gets_def)
lemma get_curr_win3_low_equal: "low_equal s1 s2 ⟹
(traps (snd (fst (get_curr_win () s1)))) =
(traps (snd (fst (get_curr_win () s2))))"
using low_equal_def get_curr_win2_low_equal by blast
lemma get_addr_low_equal: "low_equal s1 s2 ⟹
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) =
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) =
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) =
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word1)"
apply (simp add: low_equal_def)
apply (simp add: get_curr_win_def cpu_reg_val_def get_CWP_def)
apply (simp add: simpler_gets_def get_addr_def user_reg_val_def)
apply (simp add: Let_def )
apply (simp add: get_CWP_def cpu_reg_val_def get_operand2_def)
by (simp add: user_reg_val_def)
lemma get_addr2_low_equal: "low_equal s1 s2 ⟹
get_addr (snd instr) (snd (fst (get_curr_win () s1))) =
get_addr (snd instr) (snd (fst (get_curr_win () s2)))"
apply (simp add: low_equal_def)
apply (simp add: get_curr_win_def cpu_reg_val_def get_CWP_def)
apply (simp add: simpler_gets_def get_addr_def user_reg_val_def)
apply (simp add: Let_def )
apply (simp add: get_CWP_def cpu_reg_val_def get_operand2_def)
by (simp add: user_reg_val_def)
lemma sys_reg_low_equal: "low_equal s1 s2 ⟹
sys_reg s1 = sys_reg s2"
by (simp add: low_equal_def)
lemma user_reg_low_equal: "low_equal s1 s2 ⟹
user_reg s1 = user_reg s2"
by (simp add: low_equal_def)
lemma user_reg_val_low_equal: "low_equal s1 s2 ⟹
user_reg_val win ur s1 = user_reg_val win ur s2"
apply (simp add: user_reg_val_def)
by (simp add: user_reg_low_equal)
lemma get_operand2_low_equal: "low_equal s1 s2 ⟹
get_operand2 op_list s1 = get_operand2 op_list s2"
apply (simp add: get_operand2_def)
apply (simp add: cpu_reg_val_low_equal)
apply auto
apply (simp add: user_reg_val_def)
using user_reg_low_equal by fastforce
lemma mem_val_mod_cache: "mem_val_alt asi a s =
mem_val_alt asi a (s⦇cache := new_cache⦈)"
apply (simp add: mem_val_alt_def)
by (simp add: Let_def)
lemma mem_val_w32_mod_cache: "mem_val_w32 asi a s =
mem_val_w32 asi a (s⦇cache := new_cache⦈)"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
by (metis mem_val_mod_cache)
lemma load_word_mem_mod_cache:
"load_word_mem s addr asi =
load_word_mem (s⦇cache := new_cache⦈) addr asi"
apply (simp add: load_word_mem_def)
apply (case_tac "virt_to_phys addr (mmu s) (mem s) = None")
apply auto
by (simp add: mem_val_w32_mod_cache)
lemma memory_read_8_mod_cache:
"fst (memory_read 8 addr s) = fst (memory_read 8 addr (s⦇cache := new_cache⦈))"
apply (simp add: memory_read_def)
apply (case_tac "sys_reg s CCR AND 1 ≠ 0")
apply auto
apply (simp add: option.case_eq_if load_word_mem_mod_cache)
apply (auto intro: load_word_mem_mod_cache)
apply (metis load_word_mem_mod_cache option.distinct(1))
by (metis load_word_mem_mod_cache option.distinct(1))
lemma memory_read_10_mod_cache:
"fst (memory_read 10 addr s) = fst (memory_read 10 addr (s⦇cache := new_cache⦈))"
apply (simp add: memory_read_def)
apply (case_tac "sys_reg s CCR AND 1 ≠ 0")
apply auto
apply (simp add: option.case_eq_if load_word_mem_mod_cache)
apply (auto intro: load_word_mem_mod_cache)
apply (metis load_word_mem_mod_cache option.distinct(1))
by (metis load_word_mem_mod_cache option.distinct(1))
lemma mem_equal_mod_cache: "mem_equal s1 s2 pa ⟹
mem_equal (s1⦇cache := new_cache1⦈) (s2⦇cache := new_cache2⦈) pa"
by (simp add: mem_equal_def)
lemma user_accessible_mod_cache: "user_accessible (s⦇cache := new_cache⦈) pa =
user_accessible s pa"
by (simp add: user_accessible_def)
lemma mem_equal_mod_user_reg: "mem_equal s1 s2 pa ⟹
mem_equal (s1⦇user_reg := new_user_reg1⦈) (s2⦇user_reg := user_reg2⦈) pa"
by (simp add: mem_equal_def)
lemma user_accessible_mod_user_reg: "user_accessible (s⦇user_reg := new_user_reg⦈) pa =
user_accessible s pa"
by (simp add: user_accessible_def)
lemma mem_equal_mod_cpu_reg: "mem_equal s1 s2 pa ⟹
mem_equal (s1⦇cpu_reg := new_cpu1⦈) (s2⦇cpu_reg := cpu_reg2⦈) pa"
by (simp add: mem_equal_def)
lemma user_accessible_mod_cpu_reg: "user_accessible (s⦇cpu_reg := new_cpu_reg⦈) pa =
user_accessible s pa"
by (simp add: user_accessible_def)
lemma mem_equal_mod_trap: "mem_equal s1 s2 pa ⟹
mem_equal (s1⦇traps := new_traps1⦈) (s2⦇traps := traps2⦈) pa"
by (simp add: mem_equal_def)
lemma user_accessible_mod_trap: "user_accessible (s⦇traps := new_traps⦈) pa =
user_accessible s pa"
by (simp add: user_accessible_def)
lemma mem_equal_annul: "mem_equal s1 s2 pa ⟹
mem_equal (s1⦇state_var := new_state_var,
cpu_reg := new_cpu_reg⦈) (s2⦇state_var := new_state_var2,
cpu_reg := new_cpu_reg2⦈) pa"
by (simp add: mem_equal_def)
lemma user_accessible_annul: "user_accessible (s⦇state_var := new_state_var,
cpu_reg := new_cpu_reg⦈) pa =
user_accessible s pa"
by (simp add: user_accessible_def)
lemma mem_val_alt_10_mem_equal_0: "mem_equal s1 s2 pa ⟹
mem_val_alt 10 (pa AND 68719476732) s1 = mem_val_alt 10 (pa AND 68719476732) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_mem_equal_1: "mem_equal s1 s2 pa ⟹
mem_val_alt 10 ((pa AND 68719476732) + 1) s1 = mem_val_alt 10 ((pa AND 68719476732) + 1) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_mem_equal_2: "mem_equal s1 s2 pa ⟹
mem_val_alt 10 ((pa AND 68719476732) + 2) s1 = mem_val_alt 10 ((pa AND 68719476732) + 2) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_mem_equal_3: "mem_equal s1 s2 pa ⟹
mem_val_alt 10 ((pa AND 68719476732) + 3) s1 = mem_val_alt 10 ((pa AND 68719476732) + 3) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_mem_equal:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 (pa AND 68719476732) s1 = mem_val_alt 10 (pa AND 68719476732) s2 ∧
mem_val_alt 10 ((pa AND 68719476732) + 1) s1 = mem_val_alt 10 ((pa AND 68719476732) + 1) s2 ∧
mem_val_alt 10 ((pa AND 68719476732) + 2) s1 = mem_val_alt 10 ((pa AND 68719476732) + 2) s2 ∧
mem_val_alt 10 ((pa AND 68719476732) + 3) s1 = mem_val_alt 10 ((pa AND 68719476732) + 3) s2"
using mem_val_alt_10_mem_equal_0 mem_val_alt_10_mem_equal_1
mem_val_alt_10_mem_equal_2 mem_val_alt_10_mem_equal_3 a1
by blast
lemma mem_val_w32_10_mem_equal:
assumes a1: "mem_equal s1 s2 a"
shows "mem_val_w32 10 a s1 = mem_val_w32 10 a s2"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
using mem_val_alt_10_mem_equal a1 apply auto
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
by fastforce
lemma mem_val_alt_8_mem_equal_0: "mem_equal s1 s2 pa ⟹
mem_val_alt 8 (pa AND 68719476732) s1 = mem_val_alt 8 (pa AND 68719476732) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_mem_equal_1: "mem_equal s1 s2 pa ⟹
mem_val_alt 8 ((pa AND 68719476732) + 1) s1 = mem_val_alt 8 ((pa AND 68719476732) + 1) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_mem_equal_2: "mem_equal s1 s2 pa ⟹
mem_val_alt 8 ((pa AND 68719476732) + 2) s1 = mem_val_alt 8 ((pa AND 68719476732) + 2) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_mem_equal_3: "mem_equal s1 s2 pa ⟹
mem_val_alt 8 ((pa AND 68719476732) + 3) s1 = mem_val_alt 8 ((pa AND 68719476732) + 3) s2"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_mem_equal:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 (pa AND 68719476732) s1 = mem_val_alt 8 (pa AND 68719476732) s2 ∧
mem_val_alt 8 ((pa AND 68719476732) + 1) s1 = mem_val_alt 8 ((pa AND 68719476732) + 1) s2 ∧
mem_val_alt 8 ((pa AND 68719476732) + 2) s1 = mem_val_alt 8 ((pa AND 68719476732) + 2) s2 ∧
mem_val_alt 8 ((pa AND 68719476732) + 3) s1 = mem_val_alt 8 ((pa AND 68719476732) + 3) s2"
using mem_val_alt_8_mem_equal_0 mem_val_alt_8_mem_equal_1
mem_val_alt_8_mem_equal_2 mem_val_alt_8_mem_equal_3 a1
by blast
lemma mem_val_w32_8_mem_equal:
assumes a1: "mem_equal s1 s2 a"
shows "mem_val_w32 8 a s1 = mem_val_w32 8 a s2"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
using mem_val_alt_8_mem_equal a1 apply auto
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
by fastforce
lemma load_word_mem_10_low_equal:
assumes a1: "low_equal s1 s2"
shows "load_word_mem s1 address 10 = load_word_mem s2 address 10"
using a1 apply (simp add: low_equal_def load_word_mem_def)
apply clarsimp
apply (case_tac "virt_to_phys address (mmu s2) (mem s2) = None")
apply auto
apply (simp add: user_accessible_def)
using mem_val_w32_10_mem_equal apply blast
apply (simp add: user_accessible_def)
using mem_val_w32_10_mem_equal by blast
lemma load_word_mem_8_low_equal:
assumes a1: "low_equal s1 s2"
shows "load_word_mem s1 address 8 = load_word_mem s2 address 8"
using a1 apply (simp add: low_equal_def load_word_mem_def)
apply clarsimp
apply (case_tac "virt_to_phys address (mmu s2) (mem s2) = None")
apply auto
apply (simp add: user_accessible_def)
using mem_val_w32_8_mem_equal user_accessible_8 apply fastforce
apply (simp add: user_accessible_def)
using mem_val_w32_8_mem_equal user_accessible_8 by fastforce
lemma mem_read_low_equal:
assumes a1: "low_equal s1 s2 ∧ asi ∈ {8,10}"
shows "fst (memory_read asi address s1) = fst (memory_read asi address s2)"
proof (cases "asi = 8")
case True
then show ?thesis using a1
apply (simp add: low_equal_def)
apply (simp add: memory_read_def)
using a1 load_word_mem_8_low_equal apply auto
apply (simp add: option.case_eq_if)
by (simp add: option.case_eq_if)
next
case False
then have "asi = 10" using a1 by auto
then show ?thesis using a1
apply (simp add: low_equal_def)
apply (simp add: memory_read_def)
using a1 load_word_mem_10_low_equal apply auto
apply (simp add: option.case_eq_if)
by (simp add: option.case_eq_if)
qed
lemma read_mem_pc_low_equal:
assumes a1: "low_equal s1 s2"
shows "fst (memory_read 8 (cpu_reg_val PC s1) s1) =
fst (memory_read 8 (cpu_reg_val PC s2) s2)"
proof -
have f2: "cpu_reg_val PC s1 = cpu_reg_val PC s2" using a1
by (simp add: low_equal_def cpu_reg_val_def)
then show ?thesis using a1 f2 mem_read_low_equal
by auto
qed
lemma dcache_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = dcache_mod c v s1 ∧
t2 = dcache_mod c v s2"
shows "low_equal t1 t2"
using a1 apply (simp add: low_equal_def)
apply (simp add: dcache_mod_def)
apply auto
apply (simp add: user_accessible_mod_cache mem_equal_mod_cache)
by (simp add: user_accessible_mod_cache mem_equal_mod_cache)
lemma add_data_cache_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = add_data_cache s1 address w bm ∧
t2 = add_data_cache s2 address w bm"
shows "low_equal t1 t2"
using a1 apply (simp add: add_data_cache_def)
apply (case_tac "bm AND 8 >> 3 = 1")
apply auto
apply (case_tac "bm AND 4 >> 2 = 1")
apply auto
apply (case_tac "bm AND 2 >> Suc 0 = 1")
apply auto
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 2 >> Suc 0 = 1")
apply auto
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 4 >> 2 = 1")
apply auto
apply (case_tac "bm AND 2 >> Suc 0 = 1")
apply auto
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
apply (case_tac "bm AND 2 >> Suc 0 = 1")
apply auto
apply (case_tac "bm AND 1 = 1")
apply auto
apply (meson dcache_mod_low_equal)
apply (meson dcache_mod_low_equal)
by (meson dcache_mod_low_equal)
lemma mem_read2_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (memory_read (10::word8) address s1) ∧
t2 = snd (memory_read (10::word8) address s2)"
shows "low_equal t1 t2"
using a1 apply (simp add: memory_read_def)
using a1 apply (auto simp add: sys_reg_low_equal mod_2_eq_odd)
using a1 apply (simp add: load_word_mem_10_low_equal)
apply (auto split: option.splits)
using add_data_cache_low_equal apply force
using add_data_cache_low_equal apply force
done
lemma mem_read_delayed_write_low_equal:
assumes a1: "low_equal s1 s2 ∧ get_delayed_pool s1 = [] ∧ get_delayed_pool s2 = []"
shows "fst (memory_read 8 (cpu_reg_val PC (delayed_pool_write s1)) (delayed_pool_write s1)) =
fst (memory_read 8 (cpu_reg_val PC (delayed_pool_write s2)) (delayed_pool_write s2))"
using a1 apply (simp add: delayed_pool_write_def)
apply (simp add: Let_def)
apply (simp add: get_delayed_write_def)
by (simp add: read_mem_pc_low_equal)
lemma global_reg_mod_low_equal:
assumes a1: "low_equal s1 s2∧
t1 = (global_reg_mod w n rd s1) ∧
t2 = (global_reg_mod w n rd s2)"
shows "low_equal t1 t2"
using a1 apply (induction n arbitrary: s1 s2)
apply clarsimp
apply auto
apply (simp add: Let_def)
apply (simp add: user_reg_low_equal)
using user_reg_state_mod_low_equal by blast
lemma out_reg_mod_low_equal:
assumes a1: "low_equal s1 s2∧
t1 = (out_reg_mod w curr_win rd s1) ∧
t2 = (out_reg_mod w curr_win rd s2)"
shows "low_equal t1 t2"
using a1 apply (simp add: out_reg_mod_def Let_def)
apply auto
apply (simp add: user_reg_low_equal)
using user_reg_state_mod_low_equal apply fastforce
apply (simp add: user_reg_low_equal)
using user_reg_state_mod_low_equal by blast
lemma in_reg_mod_low_equal:
assumes a1: "low_equal s1 s2∧
t1 = (in_reg_mod w curr_win rd s1) ∧
t2 = (in_reg_mod w curr_win rd s2)"
shows "low_equal t1 t2"
using a1 apply (simp add: in_reg_mod_def Let_def)
apply auto
apply (simp add: user_reg_low_equal)
using user_reg_state_mod_low_equal apply fastforce
apply (simp add: user_reg_low_equal)
using user_reg_state_mod_low_equal by blast
lemma user_reg_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = user_reg_mod w curr_win rd s1 ∧ t2 = user_reg_mod w curr_win rd s2"
shows "low_equal t1 t2"
proof (cases "rd = 0")
case True
then show ?thesis using a1
by (simp add: user_reg_mod_def)
next
case False
then have f1: "rd ≠ 0" by auto
then show ?thesis
proof (cases "0 < rd ∧ rd < 8")
case True
then show ?thesis using a1 f1
apply (simp add: user_reg_mod_def)
using global_reg_mod_low_equal by blast
next
case False
then have f2: "¬ (0 < rd ∧ rd < 8)" by auto
then show ?thesis
proof (cases "7 < rd ∧ rd < 16")
case True
then show ?thesis using a1 f1 f2
apply (simp add: user_reg_mod_def)
by (auto intro: out_reg_mod_low_equal)
next
case False
then have f3: "¬ (7 < rd ∧ rd < 16)" by auto
then show ?thesis
proof (cases "15 < rd ∧ rd < 24")
case True
then show ?thesis using a1 f1 f2 f3
apply (simp add: user_reg_mod_def)
apply (simp add: low_equal_def)
apply clarsimp
by (simp add: user_accessible_mod_user_reg mem_equal_mod_user_reg)
next
case False
then show ?thesis using a1 f1 f2 f3
apply (simp add: user_reg_mod_def)
by (auto intro: in_reg_mod_low_equal)
qed
qed
qed
qed
lemma virt_to_phys_low_equal: "low_equal s1 s2 ⟹
virt_to_phys addr (mmu s1) (mem s1) = virt_to_phys addr (mmu s2) (mem s2)"
by (auto simp add: low_equal_def)
lemma write_reg_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (snd (fst (write_reg w curr_win rd s1))) ∧
t2 = (snd (fst (write_reg w curr_win rd s2)))"
shows "low_equal t1 t2"
using a1 apply (simp add: write_reg_def)
apply (simp add: simpler_modify_def)
by (auto intro: user_reg_mod_low_equal)
lemma write_cpu_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (write_cpu w cr s1)) ∧
t2 = (snd (fst (write_cpu w cr s2)))"
shows "low_equal t1 t2"
using a1
apply (simp add: write_cpu_def simpler_modify_def)
apply (simp add: cpu_reg_mod_def)
apply (simp add: low_equal_def)
using user_accessible_mod_cpu_reg mem_equal_mod_cpu_reg
by metis
lemma cpu_reg_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = cpu_reg_mod w cr s1 ∧
t2 = cpu_reg_mod w cr s2"
shows "low_equal t1 t2"
using a1
apply (simp add: cpu_reg_mod_def)
apply (simp add: low_equal_def)
using user_accessible_mod_cpu_reg mem_equal_mod_cpu_reg
by metis
lemma load_sub2_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (snd (fst (load_sub2 address 10 rd curr_win w s1))) ∧
t2 = (snd (fst (load_sub2 address 10 rd curr_win w s2)))"
shows "low_equal t1 t2"
proof (cases "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) = None")
case True
then have f0: "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) = None" by auto
have f1: "low_equal (snd (fst (write_reg w curr_win (rd AND 30) s1)))
(snd (fst (write_reg w curr_win (rd AND 30) s2)))"
using a1 by (auto intro: write_reg_low_equal)
then have "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) = None ∧
fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) =
fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s2))))"
using f0 by (blast intro: mem_read_low_equal)
then have "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) = None ∧
fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s2)))) = None"
by auto
then show ?thesis using a1
apply (simp add: load_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
using f1 apply (simp add: traps_low_equal)
using f1 by (auto intro: mod_trap_low_equal)
next
case False
then have f2: "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) ≠ None"
by auto
have f3: "low_equal (snd (fst (write_reg w curr_win (rd AND 30) s1)))
(snd (fst (write_reg w curr_win (rd AND 30) s2)))"
using a1 by (auto intro: write_reg_low_equal)
then have f4: "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) =
fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s2))))"
using f2 by (blast intro: mem_read_low_equal)
then have "fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s1)))) ≠ None ∧
fst (memory_read 10 (address + 4)
(snd (fst (write_reg w curr_win (rd AND 30) s2)))) ≠ None"
using f2 by auto
then show ?thesis using a1
apply (simp add: load_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
using f4 apply clarsimp
using f3 by (auto intro: mem_read2_low_equal write_reg_low_equal)
qed
lemma load_sub3_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (load_sub3 instr curr_win rd (10::word8) address s1)) ∧
t2 = snd (fst (load_sub3 instr curr_win rd (10::word8) address s2))"
shows "low_equal t1 t2"
proof (cases "fst (memory_read 10 address s1) = None")
case True
then have "fst (memory_read 10 address s1) = None ∧
fst (memory_read 10 address s2) = None"
using a1 by (auto simp add: mem_read_low_equal)
then show ?thesis using a1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply (auto simp add: traps_low_equal)
by (auto intro: mod_trap_low_equal)
next
case False
then have f1: "fst (memory_read 10 address s1) ≠ None ∧
fst (memory_read 10 address s2) ≠ None"
using a1 by (auto simp add: mem_read_low_equal)
then show ?thesis
proof (cases "rd ≠ 0 ∧
(fst instr = load_store_type LD ∨
fst instr = load_store_type LDA ∨
fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDSB ∨
fst instr = load_store_type LDUB ∨
fst instr = load_store_type LDUBA ∨
fst instr = load_store_type LDSH ∨
fst instr = load_store_type LDSHA ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSBA)")
case True
then show ?thesis using a1 f1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: mem_read_low_equal)
by (meson mem_read2_low_equal write_reg_low_equal)
next
case False
then show ?thesis using a1 f1
apply (simp add: load_sub3_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: mem_read_low_equal)
by (meson load_sub2_low_equal mem_read2_low_equal)
qed
qed
lemma ld_asi_user:
"(fst instr = load_store_type LDSB ∨
fst instr = load_store_type LDUB ∨
fst instr = load_store_type LDUH ∨
fst instr = load_store_type LD ∨
fst instr = load_store_type LDD) ⟹
ld_asi instr 0 = 10"
apply (simp add: ld_asi_def)
by auto
lemma load_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
(fst instr = load_store_type LDSB ∨
fst instr = load_store_type LDUB ∨
fst instr = load_store_type LDUH ∨
fst instr = load_store_type LD ∨
fst instr = load_store_type LDD) ∧
t1 = snd (fst (load_sub1 instr rd 0 s1)) ∧
t2 = snd (fst (load_sub1 instr rd 0 s2))"
shows "low_equal t1 t2"
proof (cases "(fst instr = load_store_type LDD ∨ fst instr = load_store_type LDDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0 ∨
(fst instr = load_store_type LD ∨ fst instr = load_store_type LDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0 ∨
(fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSH ∨ fst instr = load_store_type LDSHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0")
case True
then have "((fst instr = load_store_type LDD ∨ fst instr = load_store_type LDDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0 ∨
(fst instr = load_store_type LD ∨ fst instr = load_store_type LDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0 ∨
(fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSH ∨ fst instr = load_store_type LDSHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0) ∧
((fst instr = load_store_type LDD ∨ fst instr = load_store_type LDDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ≠ 0 ∨
(fst instr = load_store_type LD ∨ fst instr = load_store_type LDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ≠ 0 ∨
(fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSH ∨ fst instr = load_store_type LDSHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word1) ≠ 0)"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then show ?thesis using a1
apply (simp add: load_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: get_curr_win3_low_equal)
by (auto intro: get_curr_win2_low_equal mod_trap_low_equal)
next
case False
then have f1: "¬ ((fst instr = load_store_type LDD ∨ fst instr = load_store_type LDDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0 ∨
(fst instr = load_store_type LD ∨ fst instr = load_store_type LDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0 ∨
(fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSH ∨ fst instr = load_store_type LDSHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0) ∧
¬ ((fst instr = load_store_type LDD ∨ fst instr = load_store_type LDDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ≠ 0 ∨
(fst instr = load_store_type LD ∨ fst instr = load_store_type LDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ≠ 0 ∨
(fst instr = load_store_type LDUH ∨
fst instr = load_store_type LDUHA ∨
fst instr = load_store_type LDSH ∨ fst instr = load_store_type LDSHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word1) ≠ 0)"
by (metis assms get_addr_low_equal)
show ?thesis
proof -
have "low_equal s1 s2 ⟹
low_equal (snd (fst (get_curr_win () s1)))
(snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by auto
then have f2: "low_equal s1 s2 ⟹
low_equal (snd (fst (load_sub3 instr (fst (fst (get_curr_win () s2))) rd 10
(get_addr (snd instr) (snd (fst (get_curr_win () s2))))
(snd (fst (get_curr_win () s1))))))
(snd (fst (load_sub3 instr (fst (fst (get_curr_win () s2))) rd 10
(get_addr (snd instr) (snd (fst (get_curr_win () s2))))
(snd (fst (get_curr_win () s2))))))"
using load_sub3_low_equal by blast
show ?thesis using a1
unfolding load_sub1_def simpler_gets_def bind_def h1_def h2_def Let_def case_prod_unfold
using f1 f2 apply clarsimp
by (simp add: get_addr2_low_equal get_curr_win_low_equal ld_asi_user)
qed
qed
lemma load_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
(fst instr = load_store_type LDSB ∨
fst instr = load_store_type LDUB ∨
fst instr = load_store_type LDUBA ∨
fst instr = load_store_type LDUH ∨
fst instr = load_store_type LD ∨
fst instr = load_store_type LDA ∨
fst instr = load_store_type LDD) ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
t1 = snd (fst (load_instr instr s1)) ∧ t2 = snd (fst (load_instr instr s2))"
shows "low_equal t1 t2"
proof -
have "get_S (cpu_reg_val PSR s1) = 0 ∧ get_S (cpu_reg_val PSR s2) = 0"
using a1 by (simp add: ucast_id)
then show ?thesis using a1
apply (simp add: load_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
apply clarsimp
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply (simp add: traps_low_equal)
by (auto intro: mod_trap_low_equal load_sub1_low_equal)
qed
lemma st_data0_low_equal: "low_equal s1 s2 ⟹
st_data0 instr curr_win rd addr s1 = st_data0 instr curr_win rd addr s2"
apply (simp add: st_data0_def)
by (simp add: user_reg_val_def low_equal_def)
lemma store_word_mem_low_equal_none: "low_equal s1 s2 ⟹
store_word_mem (add_data_cache s1 addr data bm) addr data bm 10 = None ⟹
store_word_mem (add_data_cache s2 addr data bm) addr data bm 10 = None"
apply (simp add: store_word_mem_def)
proof -
assume a1: "low_equal s1 s2"
assume a2: "(case virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) of None ⇒ None | Some pair ⇒ if mmu_writable (get_acc_flag (snd pair)) 10 then Some (mem_mod_w32 10 (fst pair) bm data (add_data_cache s1 addr data bm)) else None) = None"
have f3: "(if mmu_writable (get_acc_flag (snd (v1_2 (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (v1_2 (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s2 addr data bm)) else None) = (case Some (v1_2 (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) of None ⇒ if mmu_writable (get_acc_flag (snd (v1_2 (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (v1_2 (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None)"
by auto
obtain pp :: "(word36 × word8) option ⇒ word36 × word8" where
f4: "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = None ∨ virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = Some (pp (virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm))))"
by (metis (no_types) option.exhaust)
have f5: "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))"
using a1 by (meson add_data_cache_low_equal virt_to_phys_low_equal)
{ assume "Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) ≠ (case Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s1 addr data bm)) else None)"
then have "None = (if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s2 addr data bm)) else None)"
by fastforce
moreover
{ assume "(if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s2 addr data bm)) else None) ≠ (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None)"
then have "(case Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) of None ⇒ if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) ≠ (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None)"
using f3 by simp
then have "Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ≠ virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) ∨ (if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None) ≠ None"
proof -
have "(case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) = (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) ∨ Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ≠ virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) ∨ (if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None) ≠ None"
by simp
then show ?thesis
using ‹(case Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) of None ⇒ if mmu_writable (get_acc_flag (snd (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))))) 10 then Some (mem_mod_w32 10 (fst (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))))) bm data (add_data_cache s1 addr data bm)) else None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) ≠ (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None)› by force
qed
moreover
{ assume "Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ≠ virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm))"
then have "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) ≠ Some (pp (virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm))))"
using f5 by simp }
ultimately have "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) ≠ Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ∨ virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) ≠ Some (pp (virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm))))"
using a2 by force }
ultimately have "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = Some (pp (virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)))) ∧ virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ⟶ (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) = None"
by fastforce }
then have "virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = Some (pp (virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)))) ∧ virt_to_phys addr (mmu (add_data_cache s1 addr data bm)) (mem (add_data_cache s1 addr data bm)) = Some (pp (virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)))) ⟶ (case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) = None"
using a2 by force
then show "(case virt_to_phys addr (mmu (add_data_cache s2 addr data bm)) (mem (add_data_cache s2 addr data bm)) of None ⇒ None | Some p ⇒ if mmu_writable (get_acc_flag (snd p)) 10 then Some (mem_mod_w32 10 (fst p) bm data (add_data_cache s2 addr data bm)) else None) = None"
using f5 f4 by force
qed
lemma memory_write_asi_low_equal_none: "low_equal s1 s2 ⟹
memory_write_asi 10 addr bm data s1 = None ⟹
memory_write_asi 10 addr bm data s2 = None"
apply (simp add: memory_write_asi_def)
by (simp add: store_word_mem_low_equal_none)
lemma memory_write_low_equal_none: "low_equal s1 s2 ⟹
memory_write 10 addr bm data s1 = None ⟹
memory_write 10 addr bm data s2 = None"
apply (simp add: memory_write_def)
by (metis map_option_case memory_write_asi_low_equal_none option.map_disc_iff)
lemma memory_write_low_equal_none2: "low_equal s1 s2 ⟹
memory_write 10 addr bm data s2 = None ⟹
memory_write 10 addr bm data s1 = None"
apply (simp add: memory_write_def)
by (metis low_equal_com memory_write_def memory_write_low_equal_none)
lemma mem_context_val_9_unchanged:
"mem_context_val 9 addr1 (mem s1) =
mem_context_val 9 addr1
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))"
apply (simp add: mem_context_val_def)
by (simp add: Let_def)
lemma mem_context_val_w32_9_unchanged:
"mem_context_val_w32 9 addr1 (mem s1) =
mem_context_val_w32 9 addr1
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))"
apply (simp add: mem_context_val_w32_def)
apply (simp add: Let_def)
by (metis mem_context_val_9_unchanged)
lemma ptd_lookup_unchanged_4:
"ptd_lookup va ptp (mem s1) 4 =
ptd_lookup va ptp ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) 4"
by auto
lemma ptd_lookup_unchanged_3:
"ptd_lookup va ptp (mem s1) 3 =
ptd_lookup va ptp ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) 3"
proof (cases "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36) (mem s1) = None")
case True
then have "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36) (mem s1) = None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = None"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
by auto
next
case False
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None"
using mem_context_val_w32_9_unchanged by metis
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None ∧
(∀y. (mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36) (mem s1) = Some y) ⟶
(mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 12))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))= Some y))"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
apply auto
by (simp add: Let_def)
qed
lemma ptd_lookup_unchanged_2:
"ptd_lookup va ptp (mem s1) 2 =
ptd_lookup va ptp ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) 2"
proof (cases "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36) (mem s1) = None")
case True
then have "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36) (mem s1) = None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = None"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
by auto
next
case False
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None"
using mem_context_val_w32_9_unchanged by metis
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None ∧
(∀y. (mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36) (mem s1) = Some y) ⟶
(mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 18))::word6))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))= Some y))"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
apply auto
using ptd_lookup_unchanged_3
unfolding Let_def
by auto
qed
lemma ptd_lookup_unchanged_1:
"ptd_lookup va ptp (mem s1) 1 =
ptd_lookup va ptp ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) 1"
proof (cases "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36) (mem s1) = None")
case True
then have "mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36) (mem s1) = None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = None"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
by auto
next
case False
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None"
using mem_context_val_w32_9_unchanged by metis
then have "mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36) (mem s1) ≠ None ∧
mem_context_val_w32 9 ((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None ∧
(∀y. (mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36) (mem s1) = Some y) ⟶
(mem_context_val_w32 9
((ucast (ptp OR ((ucast ((ucast (va >> 24))::word8))::word32)))::word36)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))= Some y))"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
apply auto
using ptd_lookup_unchanged_2
unfolding Let_def
proof -
fix y :: word32
have "(y AND 3 ≠ 0 ∨ y AND 3 = 0 ∨ (y AND 3 ≠ 1 ∨ ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) = None) ∧ (y AND 3 = 1 ∨ y AND 3 ≠ 2 ∨ None = Some ((ucast (ucast (y >> 8)::word24) << 12) OR (ucast (ucast va::word12)::word36), ucast y::word8))) ∧ (y AND 3 = 0 ∨ (y AND 3 ≠ 1 ∨ (y AND 3 ≠ 0 ∨ ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) = None) ∧ (y AND 3 = 0 ∨ (y AND 3 ≠ 1 ∨ ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) = ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1)) ∧ (y AND 3 = 1 ∨ (y AND 3 ≠ 2 ∨ ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) = Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y)) ∧ (y AND 3 = 2 ∨ ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) = None)))) ∧ (y AND 3 = 1 ∨ (y AND 3 ≠ 2 ∨ (y AND 3 ≠ 0 ∨ None = Some ((ucast (ucast (y >> 8)::word24) << 12) OR (ucast (ucast va::word12)::word36), ucast y::word8)) ∧ (y AND 3 = 0 ∨ (y AND 3 ≠ 1 ∨ ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) = Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y)) ∧ (y AND 3 = 1 ∨ y AND 3 = 2 ∨ None = Some ((ucast (ucast (y >> 8)::word24) << 12) OR (ucast (ucast va::word12)::word36), ucast y::word8)))) ∧ (y AND 3 = 2 ∨ y AND 3 = 0 ∨ (y AND 3 ≠ 1 ∨ ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) = None) ∧ (y AND 3 = 1 ∨ y AND 3 ≠ 2 ∨ None = Some ((ucast (ucast (y >> 8)::word24) << 12) OR (ucast (ucast va::word12)::word36), ucast y::word8))))) ∨ (∀w. mem s1 w = ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) w)"
by (metis (no_types) One_nat_def Suc_1 Suc_eq_plus1 ptd_lookup_unchanged_2)
then show "(if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) = (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None)"
proof -
have f1: "2 = Suc 0 + 1"
by (metis One_nat_def Suc_1 Suc_eq_plus1)
{ assume "y AND 3 = 1"
moreover
{ assume "y AND 3 = 1 ∧ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) ≠ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None)"
have "y AND 3 = 1 ∧ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) ≠ ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) ∨ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) = (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None)"
by presburger
moreover
{ assume "y AND 3 = 1 ∧ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) ≠ ptd_lookup va (y AND 4294967292) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) (Suc 0 + 1)"
then have "y AND 3 = 1 ∧ (if y AND 3 = 0 then None else if y AND 3 = 1 then ptd_lookup va (y AND 4294967292) (mem s1) (Suc 0 + 1) else if y AND 3 = 2 then Some ((ucast (ucast (y >> 8)::word24) << 12) OR ucast (ucast va::word12), ucast y) else None) ≠ ptd_lookup va (y AND 4294967292) (mem s1) 2"
by (metis One_nat_def Suc_1 Suc_eq_plus1 ptd_lookup_unchanged_2)
then have ?thesis
using f1 by auto }
ultimately have ?thesis
by blast }
ultimately have ?thesis
by blast }
then show ?thesis
by presburger
qed
qed
qed
lemma virt_to_phys_unchanged_sub1:
assumes a1: "(let context_table_entry = (v1 >> 11 << 11) OR (v2 AND 511 << 2)
in Let (mem_context_val_w32 (word_of_int 9) (ucast context_table_entry) (mem s1))
(case_option None (λlvl1_page_table. ptd_lookup va lvl1_page_table (mem s1) 1))) =
(let context_table_entry = (v1 >> 11 << 11) OR (v2 AND 511 << 2)
in Let (mem_context_val_w32 (word_of_int 9) (ucast context_table_entry) (mem s2))
(case_option None (λlvl1_page_table. ptd_lookup va lvl1_page_table (mem s2) 1)))"
shows "(let context_table_entry = (v1 >> 11 << 11) OR (v2 AND 511 << 2)
in Let (mem_context_val_w32 (word_of_int 9) (ucast context_table_entry)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))))
(case_option None (λlvl1_page_table. ptd_lookup va lvl1_page_table
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1))) =
(let context_table_entry = (v1 >> 11 << 11) OR (v2 AND 511 << 2)
in Let (mem_context_val_w32 (word_of_int 9) (ucast context_table_entry)
((mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))))
(case_option None (λlvl1_page_table. ptd_lookup va lvl1_page_table
((mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) 1)))"
proof -
from a1 have
"(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s1) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s1) 1) =
(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1)"
unfolding Let_def by auto
then have "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2)))
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s1) 1) =
(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2)))
((mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1)"
using mem_context_val_w32_9_unchanged
by (metis word_numeral_alt)
then have "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2)))
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1) =
(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2)))
((mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table
((mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) 1)"
using ptd_lookup_unchanged_1
proof -
obtain ww :: "word32 option ⇒ word32" where
f1: "∀z. (z = None ∨ z = Some (ww z)) ∧ (z ≠ None ∨ (∀w. z ≠ Some w))"
by moura
then have f2: "(mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = None ∨ mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = Some (ww (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None)))))) ∧ (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None ∨ (∀w. mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ Some w))"
by blast
then have f3: "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1) ≠ None ⟶ (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1) = (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w (mem s1) 1)"
by (metis (no_types) ‹⋀val va s1 ptp addr. ptd_lookup va ptp (mem s1) 1 = ptd_lookup va ptp ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1› option.case(2) option.simps(4))
have f4: "mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) = Some (ww (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))))) ∧ mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) = Some (ww (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))))) ⟶ (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1) = (case Some (ww (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) 1)"
by (metis (no_types) ‹(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s1) 1) = (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1)› ‹⋀val va s1 ptp addr. ptd_lookup va ptp (mem s1) 1 = ptd_lookup va ptp ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1› option.case(2))
have f5: "(mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) = None ∨ mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) = Some (ww (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None)))))) ∧ (mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) ≠ None ∨ (∀w. mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) ≠ Some w))"
using f1 by blast
{ assume "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1) ≠ (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) 1)"
{ assume "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w (mem s2) 1) ≠ None ∧ (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w (mem s2) 1) ≠ None"
then have "(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some w ⇒ ptd_lookup va w (mem s2) 1) ≠ None ∧ mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) ≠ None"
by (metis (no_types) ‹(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s1) 1) = (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1)› option.simps(4))
then have ?thesis
using f5 f4 f2 by force }
then have ?thesis
using f5 f3 by (metis (no_types) ‹(case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s1) 1) = (case mem_context_val_w32 (word_of_int 9) (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2) (10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1)› ‹⋀val va s1 ptp addr. ptd_lookup va ptp (mem s1) 1 = ptd_lookup va ptp ((mem s1) (10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) 1› option.case(2) option.simps(4)) }
then show ?thesis
by blast
qed
then show ?thesis
unfolding Let_def by auto
qed
lemma virt_to_phys_unchanged:
assumes a1: "(∀va. virt_to_phys va (mmu s2) (mem s1) = virt_to_phys va (mmu s2) (mem s2))"
shows "(∀va. virt_to_phys va (mmu s2) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) =
virt_to_phys va (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))))"
proof (cases "registers (mmu s2) CR AND 1 ≠ 0")
case True
then have f1: "registers (mmu s2) CR AND 1 ≠ 0" by auto
then show ?thesis
proof (cases "mmu_reg_val (mmu s2) 256 = None")
case True
then show ?thesis
by (simp add: virt_to_phys_def)
next
case False
then have f2: "mmu_reg_val (mmu s2) 256 ≠ None" by auto
then show ?thesis
proof (cases "mmu_reg_val (mmu s2) 512 = None")
case True
then show ?thesis using f1 f2
apply (simp add: virt_to_phys_def)
by auto
next
case False
then show ?thesis using f1 f2 a1
apply (simp add: virt_to_phys_def)
apply clarify
using virt_to_phys_unchanged_sub1 by fastforce
qed
qed
next
case False
then show ?thesis
by (simp add: virt_to_phys_def)
qed
lemma virt_to_phys_unchanged2_sub1:
"(case mem_context_val_w32 (word_of_int 9)
(ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table (mem s2) 1) =
(case mem_context_val_w32 (word_of_int 9)
(ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2)
(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) of
None ⇒ None | Some lvl1_page_table ⇒ ptd_lookup va lvl1_page_table ((mem s2)
(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) 1)"
proof (cases "mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) = None")
case True
then have "mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) = None ∧
mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2)
(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) = None"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
by auto
next
case False
then have "mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) ≠ None ∧
(∀y. mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) (mem s2) = Some y ⟶
mem_context_val_w32 9 (ucast ((v1 >> 11 << 11) OR (v2 AND 511 << 2))) ((mem s2)
(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))) = Some y)"
using mem_context_val_w32_9_unchanged by metis
then show ?thesis
using ptd_lookup_unchanged_1 by fastforce
qed
lemma virt_to_phys_unchanged2:
"virt_to_phys va (mmu s2) (mem s2) =
virt_to_phys va (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None)))"
proof (cases "registers (mmu s2) CR AND 1 ≠ 0")
case True
then have f1: "registers (mmu s2) CR AND 1 ≠ 0" by auto
then show ?thesis
proof (cases "mmu_reg_val (mmu s2) 256 = None")
case True
then show ?thesis
by (simp add: virt_to_phys_def)
next
case False
then have f2: "mmu_reg_val (mmu s2) 256 ≠ None" by auto
then show ?thesis
proof (cases "mmu_reg_val (mmu s2) 512 = None")
case True
then show ?thesis using f1 f2
apply (simp add: virt_to_phys_def)
by auto
next
case False
then show ?thesis
using f1 f2
apply (simp add: virt_to_phys_def)
apply clarify
unfolding Let_def
using virt_to_phys_unchanged2_sub1
by auto
qed
qed
next
case False
then show ?thesis
by (simp add: virt_to_phys_def)
qed
lemma virt_to_phys_unchanged_low_equal:
assumes a1: "low_equal s1 s2"
shows "(∀va. virt_to_phys va (mmu s2) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) =
virt_to_phys va (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))))"
using a1 apply (simp add: low_equal_def)
using virt_to_phys_unchanged
by metis
lemma mmu_low_equal: "low_equal s1 s2 ⟹ mmu s1 = mmu s2"
by (simp add: low_equal_def)
lemma mem_val_alt_8_unchanged0:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 (pa AND 68719476732) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 (pa AND 68719476732) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_unchanged1:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 ((pa AND 68719476732) + 1) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 1) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_unchanged2:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 ((pa AND 68719476732) + 2) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 2) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_unchanged3:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 ((pa AND 68719476732) + 3) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 3) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_8_unchanged:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 8 (pa AND 68719476732) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 (pa AND 68719476732) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 8 ((pa AND 68719476732) + 1) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 1) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 8 ((pa AND 68719476732) + 2) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 2) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 8 ((pa AND 68719476732) + 3) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 8 ((pa AND 68719476732) + 3) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
using a1 mem_val_alt_8_unchanged0 mem_val_alt_8_unchanged1
mem_val_alt_8_unchanged2 mem_val_alt_8_unchanged3
by blast
lemma mem_val_w32_8_unchanged:
assumes a1: "mem_equal s1 s2 a"
shows "mem_val_w32 8 a (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_w32 8 a (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
using mem_val_alt_8_unchanged a1 apply auto
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
by fastforce
lemma load_word_mem_8_unchanged:
assumes a1: "low_equal s1 s2 ∧
load_word_mem s1 addra 8 = load_word_mem s2 addra 8"
shows "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 8 =
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 8"
proof (cases "virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = None")
case True
then have "virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = None ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = None"
using a1 apply (auto simp add: mmu_low_equal)
using a1 virt_to_phys_unchanged_low_equal by metis
then show ?thesis
by (simp add: load_word_mem_def)
next
case False
then have "∃p. virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = Some p"
using a1 apply (auto simp add: mmu_low_equal)
using a1 virt_to_phys_unchanged_low_equal by metis
then have "∃p. virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s1) (mem s1) = Some p ∧
virt_to_phys addra (mmu s2) (mem s2) = Some p"
using virt_to_phys_unchanged2 by metis
then show ?thesis using a1
apply (simp add: load_word_mem_def)
apply auto
apply (simp add: low_equal_def)
apply (simp add: user_accessible_def)
using mem_val_w32_8_unchanged a1 user_accessible_8
by (metis snd_conv)
qed
lemma load_word_mem_select_8:
assumes a1: "fst (case load_word_mem s1 addra 8 of None ⇒ (None, s1)
| Some w ⇒ (Some w, add_instr_cache s1 addra w 15)) =
fst (case load_word_mem s2 addra 8 of None ⇒ (None, s2)
| Some w ⇒ (Some w, add_instr_cache s2 addra w 15))"
shows "load_word_mem s1 addra 8 = load_word_mem s2 addra 8"
using a1
by (metis (mono_tags, lifting) fst_conv not_None_eq option.simps(4) option.simps(5))
lemma memory_read_8_unchanged:
assumes a1: "low_equal s1 s2 ∧
fst (memory_read 8 addra s1) = fst (memory_read 8 addra s2)"
shows "fst (memory_read 8 addra
(s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈)) =
fst (memory_read 8 addra
(s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈))"
proof (cases "sys_reg s1 CCR AND 1 = 0")
case True
then have "sys_reg s1 CCR AND 1 = 0 ∧ sys_reg s2 CCR AND 1 = 0"
using a1 sys_reg_low_equal by fastforce
then show ?thesis using a1
apply (simp add: memory_read_def)
using load_word_mem_8_unchanged by blast
next
case False
then have f1: "sys_reg s1 CCR AND 1 ≠ 0 ∧ sys_reg s2 CCR AND 1 ≠ 0"
using a1 sys_reg_low_equal by fastforce
then show ?thesis using a1
proof (cases "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 8 = None")
case True
then have "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 8 = None ∧
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 8 = None"
using a1 f1
apply (simp add: memory_read_def)
apply clarsimp
using load_word_mem_select_8 load_word_mem_8_unchanged
by fastforce
then show ?thesis
by (simp add: memory_read_def)
next
case False
then have "∃y. load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 8 = Some y" by auto
then have "∃y. load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 8 = Some y ∧
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 8 = Some y"
using a1 f1
apply (simp add: memory_read_def)
apply clarsimp
using load_word_mem_select_8 load_word_mem_8_unchanged by fastforce
then show ?thesis using a1 f1
apply (simp add: memory_read_def)
by auto
qed
qed
lemma mem_val_alt_mod:
assumes a1: "addr1 ≠ addr2"
shows "mem_val_alt 10 addr1 s =
mem_val_alt 10 addr1 (s⦇mem := (mem s)(10 := mem s 10(addr2 ↦ val),
11 := (mem s 11)(addr2 := None))⦈)"
using a1 apply (simp add: mem_val_alt_def)
by (simp add: Let_def)
lemma mem_val_alt_mod2:
"mem_val_alt 10 addr (s⦇mem := (mem s)(10 := mem s 10(addr ↦ val),
11 := (mem s 11)(addr := None))⦈) = Some val"
by (simp add: mem_val_alt_def)
lemma mem_val_alt_10_unchanged0:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 (pa AND 68719476732) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 (pa AND 68719476732) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_unchanged1:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 ((pa AND 68719476732) + 1) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 1) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_unchanged2:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 ((pa AND 68719476732) + 2) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 2) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_unchanged3:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 ((pa AND 68719476732) + 3) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 3) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_alt_def)
apply (simp add: Let_def)
using a1 apply (simp add: mem_equal_def)
by (metis option.distinct(1))
lemma mem_val_alt_10_unchanged:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_val_alt 10 (pa AND 68719476732) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 (pa AND 68719476732) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 10 ((pa AND 68719476732) + 1) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 1) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 10 ((pa AND 68719476732) + 2) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 2) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) ∧
mem_val_alt 10 ((pa AND 68719476732) + 3) (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_alt 10 ((pa AND 68719476732) + 3) (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
using a1 mem_val_alt_10_unchanged0 mem_val_alt_10_unchanged1
mem_val_alt_10_unchanged2 mem_val_alt_10_unchanged3
by blast
lemma mem_val_w32_10_unchanged:
assumes a1: "mem_equal s1 s2 a"
shows "mem_val_w32 10 a (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) =
mem_val_w32 10 a (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)"
apply (simp add: mem_val_w32_def)
apply (simp add: Let_def)
using mem_val_alt_10_unchanged a1 apply auto
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
apply fastforce
by fastforce
lemma is_accessible: "low_equal s1 s2 ⟹
virt_to_phys addra (mmu s1) (mem s1) = Some (a, b) ⟹
virt_to_phys addra (mmu s2) (mem s2) = Some (a, b) ⟹
mmu_readable (get_acc_flag b) 10 ⟹
mem_equal s1 s2 a"
apply (simp add: low_equal_def)
apply (simp add: user_accessible_def)
by fastforce
lemma load_word_mem_10_unchanged:
assumes a1: "low_equal s1 s2 ∧
load_word_mem s1 addra 10 = load_word_mem s2 addra 10"
shows "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 10 =
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 10"
proof (cases "virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = None")
case True
then have "virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = None ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = None"
using a1 apply (auto simp add: mmu_low_equal)
using a1 virt_to_phys_unchanged_low_equal by metis
then show ?thesis
by (simp add: load_word_mem_def)
next
case False
then have "∃p. virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = Some p"
using a1 apply (auto simp add: mmu_low_equal)
using a1 virt_to_phys_unchanged_low_equal by metis
then have "∃p. virt_to_phys addra (mmu s1) ((mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s2) ((mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))) = Some p ∧
virt_to_phys addra (mmu s1) (mem s1) = Some p ∧
virt_to_phys addra (mmu s2) (mem s2) = Some p"
using virt_to_phys_unchanged2 by metis
then show ?thesis using a1
apply (simp add: load_word_mem_def)
apply auto
apply (simp add: low_equal_def)
apply (simp add: user_accessible_def)
using mem_val_w32_10_unchanged a1 by metis
qed
lemma load_word_mem_select_10:
assumes a1: "fst (case load_word_mem s1 addra 10 of None ⇒ (None, s1)
| Some w ⇒ (Some w, add_data_cache s1 addra w 15)) =
fst (case load_word_mem s2 addra 10 of None ⇒ (None, s2)
| Some w ⇒ (Some w, add_data_cache s2 addra w 15))"
shows "load_word_mem s1 addra 10 = load_word_mem s2 addra 10"
using a1
by (metis (mono_tags, lifting) fst_conv not_None_eq option.simps(4) option.simps(5))
lemma memory_read_10_unchanged:
assumes a1: "low_equal s1 s2 ∧
fst (memory_read 10 addra s1) = fst (memory_read 10 addra s2)"
shows "fst (memory_read 10 addra
(s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈)) =
fst (memory_read 10 addra
(s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈))"
proof (cases "sys_reg s1 CCR AND 1 = 0")
case True
then have "sys_reg s1 CCR AND 1 = 0 ∧ sys_reg s2 CCR AND 1 = 0"
using a1 sys_reg_low_equal by fastforce
then show ?thesis using a1
apply (simp add: memory_read_def)
using load_word_mem_10_unchanged by blast
next
case False
then have f1: "sys_reg s1 CCR AND 1 ≠ 0 ∧ sys_reg s2 CCR AND 1 ≠ 0"
using a1 sys_reg_low_equal by fastforce
then show ?thesis using a1
proof (cases "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 10 = None")
case True
then have "load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 10 = None ∧
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 10 = None"
using a1 f1
apply (simp add: memory_read_def)
apply clarsimp
using load_word_mem_select_10 load_word_mem_10_unchanged by fastforce
then show ?thesis
by (simp add: memory_read_def)
next
case False
then have "∃y. load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 10 = Some y" by auto
then have "∃y. load_word_mem (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈) addra 10 = Some y ∧
load_word_mem (s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈) addra 10 = Some y"
using a1 f1
apply (simp add: memory_read_def)
apply clarsimp
using load_word_mem_select_10 load_word_mem_10_unchanged by fastforce
then show ?thesis using a1 f1
apply (simp add: memory_read_def)
by auto
qed
qed
lemma state_mem_mod_1011_low_equal_sub1:
assumes a1: "(∀va. virt_to_phys va (mmu s2) (mem s1) =
virt_to_phys va (mmu s2) (mem s2)) ∧
(∀pa. (∃va b. virt_to_phys va (mmu s2) (mem s2) = Some (pa, b) ∧
mmu_readable (get_acc_flag b) 10) ⟶
mem_equal s1 s2 pa) ∧
mmu s1 = mmu s2 ∧
virt_to_phys va (mmu s2)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) =
Some (pa, b) ∧
mmu_readable (get_acc_flag b) 10"
shows "mem_equal s1 s2 pa"
proof -
have "virt_to_phys va (mmu s1)
((mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))) =
Some (pa, b)"
using a1 by auto
then have "virt_to_phys va (mmu s1) (mem s1) = Some (pa, b)"
using virt_to_phys_unchanged2 by metis
then have "virt_to_phys va (mmu s2) (mem s2) = Some (pa, b)"
using a1 by auto
then show ?thesis using a1 by auto
qed
lemma mem_equal_unchanged:
assumes a1: "mem_equal s1 s2 pa"
shows "mem_equal (s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val),
11 := (mem s1 11)(addr := None))⦈)
(s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val),
11 := (mem s2 11)(addr := None))⦈)
pa"
using a1 apply (simp add: mem_equal_def)
by auto
lemma state_mem_mod_1011_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = s1⦇mem := (mem s1)(10 := mem s1 10(addr ↦ val), 11 := (mem s1 11)(addr := None))⦈ ∧
t2 = s2⦇mem := (mem s2)(10 := mem s2 10(addr ↦ val), 11 := (mem s2 11)(addr := None))⦈"
shows "low_equal t1 t2"
using a1
apply (simp add: low_equal_def)
apply (simp add: user_accessible_def)
apply auto
apply (simp add: assms virt_to_phys_unchanged_low_equal)
using state_mem_mod_1011_low_equal_sub1 mem_equal_unchanged
apply metis
apply (metis virt_to_phys_unchanged2)
using state_mem_mod_1011_low_equal_sub1 mem_equal_unchanged
by metis
lemma mem_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = (mem_mod 10 addr val s1) ∧
t2 = (mem_mod 10 addr val s2)"
shows "low_equal t1 t2"
using a1
apply (simp add: mem_mod_def)
by (auto intro: state_mem_mod_1011_low_equal)
lemma mem_mod_w32_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = mem_mod_w32 10 a bm data s1 ∧
t2 = mem_mod_w32 10 a bm data s2"
shows "low_equal t1 t2"
using a1
apply (simp add: mem_mod_w32_def)
apply (simp add: Let_def)
by (meson mem_mod_low_equal)
lemma store_word_mem_low_equal:
assumes a1: "low_equal s1 s2 ∧
Some t1 = store_word_mem s1 addr data bm 10 ∧
Some t2 = store_word_mem s2 addr data bm 10"
shows "low_equal t1 t2" using a1
apply (simp add: store_word_mem_def)
apply (auto simp add: virt_to_phys_low_equal)
apply (case_tac "virt_to_phys addr (mmu s2) (mem s2) = None")
apply auto
apply (case_tac "mmu_writable (get_acc_flag b) 10")
apply auto
using mem_mod_w32_low_equal by blast
lemma memory_write_asi_low_equal:
assumes a1: "low_equal s1 s2 ∧
Some t1 = memory_write_asi 10 addr bm data s1 ∧
Some t2 = memory_write_asi 10 addr bm data s2"
shows "low_equal t1 t2"
using a1 apply (simp add: memory_write_asi_def)
by (meson add_data_cache_low_equal store_word_mem_low_equal)
lemma store_barrier_pending_mod_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = store_barrier_pending_mod False s1 ∧
t2 = store_barrier_pending_mod False s2"
shows "low_equal t1 t2"
using a1 apply (simp add: store_barrier_pending_mod_def)
apply clarsimp
using a1 apply (auto simp add: state_var_low_equal)
by (auto intro: state_var2_low_equal)
lemma memory_write_low_equal:
assumes a1: "low_equal s1 s2 ∧
Some t1 = memory_write 10 addr bm data s1 ∧
Some t2 = memory_write 10 addr bm data s2"
shows "low_equal t1 t2"
apply (case_tac "memory_write_asi 10 addr bm data s1 = None")
using a1 apply (simp add: memory_write_def)
apply (case_tac "memory_write_asi 10 addr bm data s2 = None")
apply (meson assms low_equal_com memory_write_asi_low_equal_none)
using a1 apply (simp add: memory_write_def)
apply auto
by (metis memory_write_asi_low_equal store_barrier_pending_mod_low_equal)
lemma memory_write_low_equal2:
assumes a1: "low_equal s1 s2 ∧
Some t1 = memory_write 10 addr bm data s1"
shows "∃t2. Some t2 = memory_write 10 addr bm data s2"
using a1
apply (simp add: memory_write_def)
apply auto
by (metis (full_types) memory_write_def memory_write_low_equal_none2 not_None_eq)
lemma store_sub2_low_equal_sub1:
assumes a1: "low_equal s1 s2 ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s1 = Some y ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 = Some ya"
shows "low_equal (y⦇traps := insert data_access_exception (traps y)⦈)
(ya⦇traps := insert data_access_exception (traps ya)⦈)"
proof -
from a1 have f1: "low_equal y ya" using memory_write_low_equal by metis
then have "traps y = traps ya" by (simp add: low_equal_def)
then show ?thesis using f1 mod_trap_low_equal by fastforce
qed
lemma store_sub2_low_equal_sub2:
assumes a1: "low_equal s1 s2 ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s1 = Some y ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 = Some ya ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) y) y = None ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) ya) ya = Some yb"
shows "False"
proof -
from a1 have f1: "low_equal y ya" using memory_write_low_equal by metis
then have "(user_reg_val curr_win (rd OR 1) y) =
(user_reg_val curr_win (rd OR 1) ya)"
by (simp add: low_equal_def user_reg_val_def)
then show ?thesis using a1
using f1 memory_write_low_equal_none by fastforce
qed
lemma store_sub2_low_equal_sub3:
assumes a1: "low_equal s1 s2 ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s1 = Some y ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 = Some ya ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) y) y = Some yb ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) ya) ya = None"
shows "False"
proof -
from a1 have f1: "low_equal y ya" using memory_write_low_equal by metis
then have "(user_reg_val curr_win (rd OR 1) y) =
(user_reg_val curr_win (rd OR 1) ya)"
by (simp add: low_equal_def user_reg_val_def)
then show ?thesis using a1
using f1 memory_write_low_equal_none2 by fastforce
qed
lemma store_sub2_low_equal_sub4:
assumes a1: "low_equal s1 s2 ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s1 = Some y ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 = Some ya ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) y) y = Some yb ∧
memory_write 10 (addr + 4) 15 (user_reg_val curr_win (rd OR 1) ya) ya = Some yc"
shows "low_equal yb yc"
proof -
from a1 have f1: "low_equal y ya" using memory_write_low_equal by metis
then have "(user_reg_val curr_win (rd OR 1) y) =
(user_reg_val curr_win (rd OR 1) ya)"
by (simp add: low_equal_def user_reg_val_def)
then show ?thesis using a1 f1
by (metis memory_write_low_equal)
qed
lemma store_sub2_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (store_sub2 instr curr_win rd 10 addr s1)) ∧
t2 = snd (fst (store_sub2 instr curr_win rd 10 addr s2))"
shows "low_equal t1 t2"
proof (cases "memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s1) s1 = None")
case True
then have "memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s1) s1 = None ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 = None"
using a1 by (metis memory_write_low_equal_none st_data0_low_equal)
then show ?thesis using a1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold return_def)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
using mod_trap_low_equal traps_low_equal by fastforce
next
case False
then have f1: "memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s1) s1 ≠ None ∧
memory_write 10 addr (st_byte_mask instr addr)
(st_data0 instr curr_win rd addr s2) s2 ≠ None"
using a1 by (metis memory_write_low_equal_none2 st_data0_low_equal)
then show ?thesis
proof (cases "(fst instr) ∈ {load_store_type STD,load_store_type STDA}")
case True
then show ?thesis using a1 f1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def)
apply (simp add: bind_def case_prod_unfold)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: case_prod_unfold bind_def h1_def h2_def Let_def simpler_modify_def)
apply (simp add: simpler_gets_def)
apply auto
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply (simp add: st_data0_low_equal)
apply (simp add: store_sub2_low_equal_sub1)
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub2 apply blast
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub3 apply blast
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub4 apply blast
apply (simp add: st_data0_low_equal)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
using store_sub2_low_equal_sub1 apply blast
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub2 apply blast
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub3 apply blast
apply (simp add: st_data0_low_equal)
using store_sub2_low_equal_sub4 by blast
next
case False
then show ?thesis using a1 f1
apply (simp add: store_sub2_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: simpler_modify_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def)
apply (simp add: bind_def case_prod_unfold)
apply clarsimp
apply (simp add: simpler_modify_def)
apply (simp add: st_data0_low_equal)
using memory_write_low_equal by metis
qed
qed
lemma store_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
(fst instr = load_store_type STB ∨
fst instr = load_store_type STH ∨
fst instr = load_store_type ST ∨
fst instr = load_store_type STD) ∧
t1 = snd (fst (store_sub1 instr rd 0 s1)) ∧
t2 = snd (fst (store_sub1 instr rd 0 s2))"
shows "low_equal t1 t2"
proof (cases "(fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0")
case True
then have "((fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0) ∧
((fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word1) ≠ 0)"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then show ?thesis using a1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: get_curr_win3_low_equal)
by (auto intro: get_curr_win2_low_equal mod_trap_low_equal)
next
case False
then have f1: "¬ ((fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word1) ≠ 0) ∧
¬ ((fst instr = load_store_type STH ∨ fst instr = load_store_type STHA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word1) ≠ 0)"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then show ?thesis
proof (cases "(fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0")
case True
then have "(fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0 ∧
(fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ≠ 0"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then show ?thesis using a1 f1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: get_curr_win3_low_equal)
by (auto intro: get_curr_win2_low_equal mod_trap_low_equal)
next
case False
then have "¬((fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0) ∧
¬((fst instr ∈ {load_store_type ST,load_store_type STA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ≠ 0)"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then have f2: "¬((fst instr = load_store_type ST ∨ fst instr = load_store_type STA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word2) ≠ 0) ∧
¬((fst instr = load_store_type ST ∨ fst instr = load_store_type STA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word2) ≠ 0)"
by auto
then show ?thesis
proof (cases "(fst instr ∈ {load_store_type STD,load_store_type STDA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0")
case True
then have "(fst instr ∈ {load_store_type STD,load_store_type STDA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0 ∧
(fst instr ∈ {load_store_type STD,load_store_type STDA}) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ≠ 0"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then show ?thesis using a1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply auto
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply (simp add: get_curr_win3_low_equal)
by (auto intro: get_curr_win2_low_equal mod_trap_low_equal)
next
case False
then have "¬ (fst instr ∈ {load_store_type STD, load_store_type STDA} ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0) ∧
¬ (fst instr ∈ {load_store_type STD, load_store_type STDA} ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ≠ 0)"
by (metis (mono_tags, lifting) assms get_addr_low_equal)
then have f3: "¬ ((fst instr = load_store_type STD ∨ fst instr = load_store_type STDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s1)))))::word3) ≠ 0) ∧
¬ ((fst instr = load_store_type STD ∨ fst instr = load_store_type STDA) ∧
((ucast (get_addr (snd instr) (snd (fst (get_curr_win () s2)))))::word3) ≠ 0)"
by auto
show ?thesis using a1
apply (simp add: store_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (unfold case_prod_beta)
apply (simp add: f1 f2 f3)
apply (simp_all add: st_asi_def)
using a1 apply clarsimp
apply (simp add: get_curr_win_low_equal get_addr2_low_equal)
by (metis store_sub2_low_equal get_curr_win2_low_equal)
qed
qed
qed
lemma store_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
(fst instr = load_store_type STB ∨
fst instr = load_store_type STH ∨
fst instr = load_store_type ST ∨
fst instr = load_store_type STA ∨
fst instr = load_store_type STD) ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
t1 = snd (fst (store_instr instr s1)) ∧ t2 = snd (fst (store_instr instr s2))"
shows "low_equal t1 t2"
proof -
have "get_S (cpu_reg_val PSR s1) = 0 ∧ get_S (cpu_reg_val PSR s2) = 0"
using a1 by (simp add: ucast_id)
then show ?thesis using a1
apply (simp add: store_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
apply clarsimp
apply (simp add: raise_trap_def add_trap_set_def)
apply (simp add: simpler_modify_def)
apply (simp add: traps_low_equal)
by (auto intro: mod_trap_low_equal store_sub1_low_equal)
qed
lemma sethi_low_equal: "low_equal s1 s2 ∧
t1 = snd (fst (sethi_instr instr s1)) ∧ t2 = snd (fst (sethi_instr instr s2)) ⟹
low_equal t1 t2"
apply (simp add: sethi_instr_def)
apply (simp add: Let_def)
apply (case_tac "get_operand_w5 (snd instr ! Suc 0) ≠ 0")
apply auto
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: get_curr_win_low_equal)
using get_curr_win2_low_equal write_reg_low_equal
apply metis
by (simp add: return_def)
lemma nop_low_equal: "low_equal s1 s2 ∧
t1 = snd (fst (nop_instr instr s1)) ∧ t2 = snd (fst (nop_instr instr s2)) ⟹
low_equal t1 t2"
apply (simp add: nop_instr_def)
by (simp add: return_def)
lemma logical_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (logical_instr_sub1 instr_name result s1)) ∧
t2 = snd (fst (logical_instr_sub1 instr_name result s2))"
shows "low_equal t1 t2"
proof (cases "instr_name = logic_type ANDcc ∨
instr_name = logic_type ANDNcc ∨
instr_name = logic_type ORcc ∨
instr_name = logic_type ORNcc ∨
instr_name = logic_type XORcc ∨ instr_name = logic_type XNORcc")
case True
then show ?thesis using a1
apply (simp add: logical_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: logical_new_psr_val_def)
using write_cpu_low_equal cpu_reg_val_low_equal
by fastforce
next
case False
then show ?thesis using a1
apply (simp add: logical_instr_sub1_def)
by (simp add: return_def)
qed
lemma logical_instr_low_equal: "low_equal s1 s2 ∧
t1 = snd (fst (logical_instr instr s1)) ∧ t2 = snd (fst (logical_instr instr s2)) ⟹
low_equal t1 t2"
apply (simp add: logical_instr_def)
apply (simp add: Let_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp_all add: get_curr_win_low_equal)
apply (simp_all add: get_operand2_low_equal)
using logical_instr_sub1_low_equal get_operand2_low_equal
get_curr_win2_low_equal write_reg_low_equal user_reg_val_low_equal
proof -
assume a1: "low_equal s1 s2"
assume "t2 = snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))))"
assume "t1 = snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))"
have "⋀w wa. user_reg_val w wa (snd (fst (get_curr_win () s2))) = user_reg_val w wa (snd (fst (get_curr_win () s1)))"
using a1 by (metis (no_types) get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))) (snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))))"
using a1 by (metis (no_types) get_curr_win2_low_equal logical_instr_sub1_low_equal write_reg_low_equal)
next
assume a2: "low_equal s1 s2"
assume "t1 = snd (fst (logical_instr_sub1 (fst instr)
(logical_result (fst instr)
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))))
(get_operand2 (snd instr) s2))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))))"
assume "t2 = snd (fst (logical_instr_sub1 (fst instr)
(logical_result (fst instr)
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))))
(get_operand2 (snd instr) s2))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))))))"
have "⋀w wa. user_reg_val w wa (snd (fst (get_curr_win () s2))) = user_reg_val w wa (snd (fst (get_curr_win () s1)))"
using a2 by (metis (no_types) get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal
(snd (fst (logical_instr_sub1 (fst instr)
(logical_result (fst instr)
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))))
(get_operand2 (snd instr) s2))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))))))))
(snd (fst (logical_instr_sub1 (fst instr)
(logical_result (fst instr)
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))))
(get_operand2 (snd instr) s2))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
proof -
have "low_equal (snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (logical_instr_sub1 (fst instr) (logical_result (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s2)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
by (meson a2 get_curr_win2_low_equal logical_instr_sub1_low_equal write_reg_low_equal)
then show ?thesis
using ‹⋀wa w. user_reg_val w wa (snd (fst (get_curr_win () s2))) = user_reg_val w wa (snd (fst (get_curr_win () s1)))› by presburger
qed
qed
lemma shift_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (shift_instr instr s1)) ∧ t2 = snd (fst (shift_instr instr s2))"
shows "low_equal t1 t2"
proof (cases "(fst instr = shift_type SLL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def case_prod_unfold)
apply auto
apply (simp_all add: get_curr_win_low_equal)
proof -
assume a1: "low_equal s1 s2"
assume "t2 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) << unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))"
assume "t1 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) << unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))"
have "⋀w wa wb. low_equal (snd (fst (write_reg w wa wb s1))) (snd (fst (write_reg w wa wb s2)))"
using a1 by (metis write_reg_low_equal)
then show "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) << unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) << unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using a1 by (simp add: get_curr_win_def simpler_gets_def user_reg_val_low_equal)
next
assume a2: "low_equal s1 s2"
assume "t1 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) <<
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))"
assume "t2 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) <<
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))"
have "⋀w wa wb. low_equal (snd (fst (write_reg w wa wb s1))) (snd (fst (write_reg w wa wb s2)))"
using a2 by (metis write_reg_low_equal)
then show "low_equal
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) <<
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) <<
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))"
proof -
assume a1: "⋀w wa wb. low_equal (snd (fst (write_reg w wa wb s1))) (snd (fst (write_reg w wa wb s2)))"
have "⋀u s. fst (get_curr_win u s) = (ucast (get_CWP (cpu_reg_val PSR s))::'a word, s)"
by (simp add: get_curr_win_def simpler_gets_def)
then show ?thesis
using a1 assms user_reg_val_low_equal by fastforce
qed
qed
next
case False
then have f1: "¬((fst instr = shift_type SLL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0))"
by auto
then show ?thesis
proof (cases "(fst instr = shift_type SRL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1 f1
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def case_prod_unfold)
apply auto
apply (simp_all add: get_curr_win_low_equal)
proof -
assume a1: "low_equal s1 s2"
assume "t2 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) >> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))"
assume "t1 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) >> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))"
have "⋀u s. fst (get_curr_win u s) = (ucast (get_CWP (cpu_reg_val PSR s))::'a word, s)"
by (simp add: get_curr_win_def simpler_gets_def)
then show "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) >> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) >> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using a1 user_reg_val_low_equal write_reg_low_equal by fastforce
next
assume a2: "low_equal s1 s2"
assume "t1 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) >>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))"
assume "t2 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) >>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))"
have "⋀u s. fst (get_curr_win u s) = (ucast (get_CWP (cpu_reg_val PSR s))::'a word, s)"
by (simp add: get_curr_win_def simpler_gets_def)
then show "low_equal
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) >>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) >>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))"
using a2 user_reg_val_low_equal write_reg_low_equal by fastforce
qed
next
case False
then have f2: "¬((fst instr = shift_type SRL) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0))"
by auto
then show ?thesis
proof (cases "(fst instr = shift_type SRA) ∧ (get_operand_w5 ((snd instr)!3) ≠ 0)")
case True
then show ?thesis using a1 f1 f2
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def case_prod_unfold)
apply auto
apply (simp_all add: get_curr_win_low_equal)
proof -
assume a1: "low_equal s1 s2"
assume "t1 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) >>> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))"
assume "t2 = snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) >>> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))"
have "∀w wa. user_reg_val wa w (snd (fst (get_curr_win () s1))) = user_reg_val wa w (snd (fst (get_curr_win () s2)))"
using a1 by (meson get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) >>> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s1))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) >>> unat (ucast (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 2)) (snd (fst (get_curr_win () s2))))::word5)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using a1 by (metis (no_types) get_curr_win2_low_equal write_reg_low_equal)
next
assume a2: "low_equal s1 s2"
assume "t1 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) >>>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))"
assume "t2 = snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) >>>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))"
have "∀w wa. user_reg_val wa w (snd (fst (get_curr_win () s1))) = user_reg_val wa w (snd (fst (get_curr_win () s2)))"
using a2 by (meson get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) >>>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) >>>
unat (get_operand_w5 (snd instr ! 2)))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))"
using a2 get_curr_win2_low_equal write_reg_low_equal by fastforce
qed
next
case False
then show ?thesis using a1 f1 f2
apply (simp add: shift_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def)
apply (simp add: bind_def h1_def h2_def Let_def case_prod_unfold)
apply (simp add: return_def)
using get_curr_win2_low_equal by blast
qed
qed
qed
lemma add_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (add_instr_sub1 instr_name result rs1_val operand2 s1)) ∧
t2 = snd (fst (add_instr_sub1 instr_name result rs1_val operand2 s2))"
shows "low_equal t1 t2"
proof (cases "instr_name = arith_type ADDcc ∨ instr_name = arith_type ADDXcc")
case True
then show ?thesis using a1
apply (simp add: add_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (clarsimp simp add: cpu_reg_val_low_equal)
using write_cpu_low_equal by blast
next
case False
then show ?thesis using a1
apply (simp add: add_instr_sub1_def)
by (simp add: return_def)
qed
lemma add_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (add_instr instr s1)) ∧ t2 = snd (fst (add_instr instr s2))"
shows "low_equal t1 t2"
proof -
have f1: "low_equal s1 s2 ∧
t1 = snd (fst (add_instr_sub1 (fst instr)
(if fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc
then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) +
get_operand2 (snd instr) s1
else user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) +
get_operand2 (snd instr) s1 +
ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1))))))
(user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))))
(get_operand2 (snd instr) s1)
(snd (fst (write_reg
(if get_operand_w5 (snd instr ! 3) ≠ 0
then if fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc
then user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) +
get_operand2 (snd instr) s1
else user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) +
get_operand2 (snd instr) s1 +
ucast (get_icc_C
(cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))
else user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))))) ∧
t2 = snd (fst (add_instr_sub1 (fst instr)
(if fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc
then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) +
get_operand2 (snd instr) s2
else user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) +
get_operand2 (snd instr) s2 +
ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2))))))
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))))
(get_operand2 (snd instr) s2)
(snd (fst (write_reg
(if get_operand_w5 (snd instr ! 3) ≠ 0
then if fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc
then user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) +
get_operand2 (snd instr) s2
else user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) +
get_operand2 (snd instr) s2 +
ucast (get_icc_C
(cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))
else user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))))"
using a1 apply (simp add: add_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: case_prod_unfold)
then show ?thesis
proof (cases "get_operand_w5 (snd instr ! 3) ≠ 0")
case True
then have f2: "get_operand_w5 (snd instr ! 3) ≠ 0" by auto
then show ?thesis
proof (cases "fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc")
case True
then show ?thesis
using f1 f2 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
assume "t1 = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))"
assume a2: "t2 = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))))"
have f3: "∀is. get_operand2 is s1 = get_operand2 is s2"
using a1 by (metis get_operand2_low_equal)
have f4: "fst (fst (get_curr_win () s1)) = fst (fst (get_curr_win () s2))"
using a1 by (meson get_curr_win_low_equal)
have "∀s. snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s + get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s + get_operand2 (snd instr) s2) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))) = t2 ∨ ¬ low_equal s (snd (fst (get_curr_win () s2)))"
using a2 user_reg_val_low_equal by fastforce
then show "low_equal (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))) (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))))"
using f4 f3 a2 a1 by (metis (no_types) add_instr_sub1_low_equal get_curr_win2_low_equal write_reg_low_equal)
qed
next
case False
then show ?thesis
using f1 f2 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
have f2: "∀s sa sb w wa wb sc. (¬ low_equal s sa ∨ sb ≠ snd (fst (write_reg w (wa::'a word) wb s)) ∨ sc ≠ snd (fst (write_reg w wa wb sa))) ∨ low_equal sb sc"
by (meson write_reg_low_equal)
have f3: "gets (λs. ucast (get_CWP (cpu_reg_val PSR s))::'a word) = get_curr_win ()"
by (simp add: get_curr_win_def)
then have "((ucast (get_CWP (cpu_reg_val PSR s1)), s1), False) = (fst (get_curr_win () s1), snd (get_curr_win () s1))"
by (metis (no_types) prod.collapse simpler_gets_def)
then have "(ucast (get_CWP (cpu_reg_val PSR s1)), s1) = fst (get_curr_win () s1) ∧ ¬ snd (get_curr_win () s1)"
by blast
then have f4: "ucast (get_CWP (cpu_reg_val PSR s1)) = fst (fst (get_curr_win () s1)) ∧ s1 = snd (fst (get_curr_win () s1))"
by (metis (no_types) prod.collapse prod.simps(1))
have "((ucast (get_CWP (cpu_reg_val PSR s2)), s2), False) = (fst (get_curr_win () s2), snd (get_curr_win () s2))"
using f3 by (metis (no_types) prod.collapse simpler_gets_def)
then have "(ucast (get_CWP (cpu_reg_val PSR s2)), s2) = fst (get_curr_win () s2) ∧ ¬ snd (get_curr_win () s2)"
by blast
then have f5: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2)) ∧ s2 = snd (fst (get_curr_win () s2))"
by (metis prod.collapse prod.simps(1))
then have f6: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2))) = low_equal s1 s2"
using f4 by presburger
have f7: "fst (fst (get_curr_win () s1)) = ucast (get_CWP (cpu_reg_val PSR s1))"
using f4 by presburger
have f8: "cpu_reg_val PSR s1 = cpu_reg_val PSR s2"
using a1 by (meson cpu_reg_val_low_equal)
have f9: "user_reg_val (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) = user_reg_val (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))"
using f6 a1 by (meson user_reg_val_low_equal)
have f10: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2))"
using f5 by meson
have f11: "∀s sa is. ¬ low_equal (s::'a sparc_state) sa ∨ get_operand2 is s = get_operand2 is sa"
using get_operand2_low_equal by blast
then have f12: "user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1))))) = user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))"
using f9 f8 f5 f4 a1 by auto
then have "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using f10 f8 f6 f4 f2 a1 by simp
then show "low_equal (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))) (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))))"
using f12 f11 f10 f9 f8 f7 a1 add_instr_sub1_low_equal by fastforce
qed
qed
next
case False
then have f3: "¬ get_operand_w5 (snd instr ! 3) ≠ 0" by auto
then show ?thesis
proof (cases "fst instr = arith_type ADD ∨ fst instr = arith_type ADDcc")
case True
then show ?thesis
using f1 f3 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
assume "t1 = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))"
assume "t2 = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))"
have f2: "∀is. get_operand2 is s1 = get_operand2 is s2"
using a1 by (meson get_operand2_low_equal)
have f3: "fst (fst (get_curr_win () s1)) = fst (fst (get_curr_win () s2))"
using a1 by (meson get_curr_win_low_equal)
have "∀w wa. user_reg_val wa w (snd (fst (get_curr_win () s1))) = user_reg_val wa w (snd (fst (get_curr_win () s2)))"
using a1 by (meson get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
using f3 f2 a1 by (metis (no_types) add_instr_sub1_low_equal get_curr_win2_low_equal write_reg_low_equal)
qed
next
case False
then show ?thesis
using f1 f3 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
have f2: "gets (λs. ucast (get_CWP (cpu_reg_val PSR s))::'a word) = get_curr_win ()"
by (simp add: get_curr_win_def)
then have "((ucast (get_CWP (cpu_reg_val PSR s1)), s1), False) = (fst (get_curr_win () s1), snd (get_curr_win () s1))"
by (metis (no_types) prod.collapse simpler_gets_def)
then have "(ucast (get_CWP (cpu_reg_val PSR s1)), s1) = fst (get_curr_win () s1) ∧ ¬ snd (get_curr_win () s1)"
by fastforce
then have f3: "ucast (get_CWP (cpu_reg_val PSR s1)) = fst (fst (get_curr_win () s1)) ∧ s1 = snd (fst (get_curr_win () s1))"
by (metis prod.collapse prod.simps(1))
have "((ucast (get_CWP (cpu_reg_val PSR s2)), s2), False) = (fst (get_curr_win () s2), snd (get_curr_win () s2))"
using f2 by (metis (no_types) prod.collapse simpler_gets_def)
then have "(ucast (get_CWP (cpu_reg_val PSR s2)), s2) = fst (get_curr_win () s2) ∧ ¬ snd (get_curr_win () s2)"
by fastforce
then have f4: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2)) ∧ s2 = snd (fst (get_curr_win () s2))"
by (metis (no_types) prod.collapse prod.simps(1))
then have f5: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2))) = low_equal s1 s2"
using f3 by presburger
have f6: "fst (fst (get_curr_win () s1)) = ucast (get_CWP (cpu_reg_val PSR s1))"
using f3 by auto
have f7: "cpu_reg_val PSR s1 = cpu_reg_val PSR s2"
using a1 by (meson cpu_reg_val_low_equal)
have f8: "∀s sa w wa. ¬ low_equal s sa ∨ user_reg_val (w::'a word) wa s = user_reg_val w wa sa"
by (meson user_reg_val_low_equal)
have f9: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2))"
using f4 by meson
have "∀s sa is. ¬ low_equal (s::'a sparc_state) sa ∨ get_operand2 is s = get_operand2 is sa"
using get_operand2_low_equal by blast
then have f10: "get_operand2 (snd instr) s1 = get_operand2 (snd instr) s2"
using a1 by meson
have f11: "cpu_reg_val PSR (snd (fst (get_curr_win () s2))) = cpu_reg_val PSR s1"
using f4 a1 by (simp add: cpu_reg_val_low_equal)
have f12: "user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))) = 0"
by (meson user_reg_val_def)
have "user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))) = 0"
by (meson user_reg_val_def)
then have "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))"
using f12 f9 f7 f5 f3 a1 write_reg_low_equal by fastforce
then have "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))) ∧ snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))))))) = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (if get_operand_w5 (snd instr ! Suc 0) = 0 then 0 else user_reg (snd (fst (get_curr_win () s2))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))))))) ∧ snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))) = snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (if get_operand_w5 (snd instr ! Suc 0) = 0 then 0 else user_reg (snd (fst (get_curr_win () s2))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))"
using f11 f10 f9 f8 f7 f6 f5 f3 a1 by (simp add: user_reg_val_def)
then show "low_equal (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) + get_operand2 (snd instr) s1 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (add_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) + get_operand2 (snd instr) s2 + ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
using add_instr_sub1_low_equal by blast
qed
qed
qed
qed
lemma sub_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (sub_instr_sub1 instr_name result rs1_val operand2 s1)) ∧
t2 = snd (fst (sub_instr_sub1 instr_name result rs1_val operand2 s2))"
shows "low_equal t1 t2"
proof (cases "instr_name = arith_type SUBcc ∨ instr_name = arith_type SUBXcc")
case True
then show ?thesis using a1
apply (simp add: sub_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (clarsimp simp add: cpu_reg_val_low_equal)
using write_cpu_low_equal by blast
next
case False
then show ?thesis using a1
apply (simp add: sub_instr_sub1_def)
by (simp add: return_def)
qed
lemma sub_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (sub_instr instr s1)) ∧ t2 = snd (fst (sub_instr instr s2))"
shows "low_equal t1 t2"
proof -
have f1: "low_equal s1 s2 ∧
t1 = snd (fst (sub_instr_sub1 (fst instr)
(if fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc
then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) -
get_operand2 (snd instr) s1
else user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) -
get_operand2 (snd instr) s1 -
ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1))))))
(user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))))
(get_operand2 (snd instr) s1)
(snd (fst (write_reg
(if get_operand_w5 (snd instr ! 3) ≠ 0
then if fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc
then user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) -
get_operand2 (snd instr) s1
else user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) -
get_operand2 (snd instr) s1 -
ucast (get_icc_C
(cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))
else user_reg_val (fst (fst (get_curr_win () s1)))
(get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))))) ∧
t2 = snd (fst (sub_instr_sub1 (fst instr)
(if fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc
then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) -
get_operand2 (snd instr) s2
else user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) -
get_operand2 (snd instr) s2 -
ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2))))))
(user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))))
(get_operand2 (snd instr) s2)
(snd (fst (write_reg
(if get_operand_w5 (snd instr ! 3) ≠ 0
then if fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc
then user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) -
get_operand2 (snd instr) s2
else user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) -
get_operand2 (snd instr) s2 -
ucast (get_icc_C
(cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))
else user_reg_val (fst (fst (get_curr_win () s2)))
(get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))))"
using a1 apply (simp add: sub_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: case_prod_unfold)
then show ?thesis
proof (cases "get_operand_w5 (snd instr ! 3) ≠ 0")
case True
then have f2: "get_operand_w5 (snd instr ! 3) ≠ 0" by auto
then show ?thesis
proof (cases "fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc")
case True
then show ?thesis
using f1 f2 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
assume a2: "t1 = snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))"
assume a3: "t2 = snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))))"
then have f4: "snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))) = t2"
using a1 by (simp add: get_operand2_low_equal)
have "∀s. ¬ low_equal (snd (fst (get_curr_win () s1))) s ∨ snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) s - get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))))) = t1"
using a2 a1 by (simp add: get_curr_win_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))) (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))))"
using f4 a3 a2 a1 by (metis (no_types) get_curr_win2_low_equal sub_instr_sub1_low_equal write_reg_low_equal)
qed
next
case False
then show ?thesis
using f1 f2 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
have f2: "fst (get_curr_win () s1) = (ucast (get_CWP (cpu_reg_val PSR s1)), s1)"
by (simp add: get_curr_win_def simpler_gets_def)
have f3: "cpu_reg_val PSR s1 = cpu_reg_val PSR s2"
using a1 by (meson cpu_reg_val_low_equal)
then have f4: "user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) = user_reg_val (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! Suc 0)) s1"
using f2 by simp
have f5: "∀s sa is. ¬ low_equal (s::'a sparc_state) sa ∨ get_operand2 is s = get_operand2 is sa"
using get_operand2_low_equal by blast
then have f6: "sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! Suc 0)) s2) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) = sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))"
using f4 a1 by (simp add: user_reg_val_low_equal)
have f7: "fst (get_curr_win () s2) = (ucast (get_CWP (cpu_reg_val PSR s2)), s2)"
by (simp add: get_curr_win_def simpler_gets_def)
then have f8: "user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2))))) = user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))"
using f5 f2 a1 by (simp add: cpu_reg_val_low_equal user_reg_val_low_equal)
then have f9: "sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! Suc 0)) s2) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))) = sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using f7 by fastforce
have "write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (ucast (get_CWP (cpu_reg_val PSR s2))) (get_operand_w5 (snd instr ! 3)) s2 = write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))"
using f8 f7 by simp
then have "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2))))))"
using f3 f2 a1 by (metis (no_types) prod.sel(1) prod.sel(2) write_reg_low_equal)
then show "low_equal (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s1))))))))) (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (get_curr_win () s2)))))))))"
using f9 f6 by (metis (no_types) sub_instr_sub1_low_equal)
qed
qed
next
case False
then have f3: "¬ get_operand_w5 (snd instr ! 3) ≠ 0" by auto
then show ?thesis
proof (cases "fst instr = arith_type SUB ∨ fst instr = arith_type SUBcc")
case True
then show ?thesis
using f1 f3 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
assume "t1 = snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))"
assume "t2 = snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))"
have f2: "∀is. get_operand2 is s1 = get_operand2 is s2"
using a1 get_operand2_low_equal by blast
have f3: "fst (fst (get_curr_win () s1)) = fst (fst (get_curr_win () s2))"
using a1 by (meson get_curr_win_low_equal)
have "∀w wa. user_reg_val wa w (snd (fst (get_curr_win () s1))) = user_reg_val wa w (snd (fst (get_curr_win () s2)))"
using a1 by (metis (no_types) get_curr_win2_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
using f3 f2 a1 by (metis (no_types) get_curr_win2_low_equal sub_instr_sub1_low_equal write_reg_low_equal)
qed
next
case False
then show ?thesis
using f1 f3 apply clarsimp
proof -
assume a1: "low_equal s1 s2"
have f2: "∀s sa sb w wa wb sc. (¬ low_equal s sa ∨ sb ≠ snd (fst (write_reg w (wa::'a word) wb s)) ∨ sc ≠ snd (fst (write_reg w wa wb sa))) ∨ low_equal sb sc"
by (meson write_reg_low_equal)
have "((ucast (get_CWP (cpu_reg_val PSR s1)), s1), False) = get_curr_win () s1"
by (simp add: get_curr_win_def simpler_gets_def)
then have f3: "ucast (get_CWP (cpu_reg_val PSR s1)) = fst (fst (get_curr_win () s1)) ∧ s1 = snd (fst (get_curr_win () s1))"
by (metis (no_types) prod.collapse prod.simps(1))
have "((ucast (get_CWP (cpu_reg_val PSR s2)), s2), False) = get_curr_win () s2"
by (simp add: get_curr_win_def simpler_gets_def)
then have f4: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2)) ∧ s2 = snd (fst (get_curr_win () s2))"
by (metis (no_types) prod.collapse prod.simps(1))
have f5: "∀s sa sb sc w wa wb sd. (¬ low_equal (s::'a sparc_state) sa ∨ sb ≠ snd (fst (sub_instr_sub1 sc w wa wb s)) ∨ sd ≠ snd (fst (sub_instr_sub1 sc w wa wb sa))) ∨ low_equal sb sd"
by (meson sub_instr_sub1_low_equal)
have "low_equal (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))"
using f4 f3 f2 a1 by (simp add: cpu_reg_val_low_equal user_reg_val_low_equal)
then show "low_equal (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) - get_operand2 (snd instr) s1 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))))) (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) (get_operand2 (snd instr) s1) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (sub_instr_sub1 (fst instr) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) - get_operand2 (snd instr) s2 - ucast (get_icc_C (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))))) (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) (get_operand2 (snd instr) s2) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))))))))"
using f5 f4 f3 a1 by (simp add: cpu_reg_val_low_equal get_operand2_low_equal user_reg_val_low_equal)
qed
qed
qed
qed
lemma mul_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (mul_instr_sub1 instr_name result s1)) ∧
t2 = snd (fst (mul_instr_sub1 instr_name result s2))"
shows "low_equal t1 t2"
proof (cases "instr_name ∈ {arith_type SMULcc,arith_type UMULcc}")
case True
then show ?thesis using a1
apply (simp add: mul_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (clarsimp simp add: cpu_reg_val_low_equal)
using write_cpu_low_equal by blast
next
case False
then show ?thesis using a1
apply (simp add: mul_instr_sub1_def)
by (simp add: return_def)
qed
lemma mul_instr_low_equal:
‹low_equal t1 t2›
if ‹low_equal s1 s2 ∧ t1 = snd (fst (mul_instr instr s1)) ∧ t2 = snd (fst (mul_instr instr s2))›
proof -
from that have ‹low_equal s1 s2›
and t1: ‹t1 = snd (fst (mul_instr instr s1))›
and t2: ‹t2 = snd (fst (mul_instr instr s2))›
by simp_all
have f2: "∀s sa sb sc w sd. ¬ low_equal (s::'a sparc_state) sa ∨ sb ≠ snd (fst (mul_instr_sub1 sc w s)) ∨ sd ≠ snd (fst (mul_instr_sub1 sc w sa)) ∨ low_equal sb sd"
using mul_instr_sub1_low_equal by blast
have f3: "∀s sa sb w wa wb sc. ¬ low_equal s sa ∨ sb ≠ snd (fst (write_reg w (wa::'a word) wb s)) ∨ sc ≠ snd (fst (write_reg w wa wb sa)) ∨ low_equal sb sc"
by (meson write_reg_low_equal)
have f4: "∀s sa sb w c sc. ¬ low_equal (s::'a sparc_state) sa ∨ sb ≠ snd (fst (write_cpu w c s)) ∨ sc ≠ snd (fst (write_cpu w c sa)) ∨ low_equal sb sc"
by (meson write_cpu_low_equal)
have f6: "((ucast (get_CWP (cpu_reg_val PSR s1)), s1), False) = (fst (get_curr_win () s1), snd (get_curr_win () s1))"
by (simp add: get_curr_win_def simpler_gets_def)
have f7: "fst (fst (get_curr_win () s1)) = fst (fst (get_curr_win () s2))"
using ‹low_equal s1 s2› by (meson get_curr_win_low_equal)
have "((ucast (get_CWP (cpu_reg_val PSR s2)), s2), False) = (fst (get_curr_win () s2), snd (get_curr_win () s2))"
by (simp add: get_curr_win_def simpler_gets_def)
then have f8: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2)) ∧ s2 = snd (fst (get_curr_win () s2))"
by (metis prod.collapse prod.simps(1))
then have f9: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using f6 ‹low_equal s1 s2› by (metis (no_types) prod.collapse prod.simps(1))
have f10: "∀s sa w wa. ¬ low_equal s sa ∨ user_reg_val (w::'a word) wa s = user_reg_val w wa sa"
using user_reg_val_low_equal by blast
have f11: "get_operand2 (snd instr) s1 = get_operand2 (snd instr) (snd (fst (get_curr_win () s2)))"
using f9 f6 by (metis (no_types) get_operand2_low_equal prod.collapse prod.simps(1))
then have f12: "uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2) = uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)"
using f10 f9 f8 f7 by presburger
then have f13: "(word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) ≠ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ∨ (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) ≠ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) ∨ low_equal (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))"
using f9 f4 by presburger
have "get_operand_w5 (snd instr ! 3) = 0 ∧ low_equal (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ⟶ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) = write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))"
using f10 f7 by force
then have f14: "get_operand_w5 (snd instr ! 3) ≠ 0 ∨ low_equal (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))) ∨ ¬ low_equal (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))"
using f3 by metis
then have f15: "low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∨ fst instr ≠ arith_type UMULcc ∨ get_operand_w5 (snd instr ! 3) ≠ 0 ∨ (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) ≠ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ∨ (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) ≠ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))"
using f13 f12 f2 by fastforce
have f16: "user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) = user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))"
using f10 f9 f7 by presburger
{ assume "fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
moreover
{ assume "¬ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
moreover
{ assume "low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ≠ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
moreover
{ assume "mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))))) ≠ mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))"
then have "write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ∨ fst instr ≠ arith_type UMULcc"
by fastforce }
moreover
{ assume "mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))) ≠ mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))"
then have "write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ∨ fst instr ≠ arith_type UMULcc"
by fastforce }
ultimately have "write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ∨ write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ∨ fst instr ≠ arith_type UMULcc"
by force }
ultimately have "write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ∨ write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ∨ ¬ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∨ fst instr ≠ arith_type UMULcc"
by fastforce }
ultimately have "fst instr = arith_type UMULcc ∧ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∧ write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))) = write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) ∧ write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))) = write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ⟶ get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))"
by blast }
moreover
{ assume "¬ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
moreover
{ assume "¬ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∧ snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))))) = snd (fst (mul_instr_sub1 (arith_type UMULcc) (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))))) ∧ snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))) = snd (fst (mul_instr_sub1 (arith_type UMULcc) (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))"
then have "¬ low_equal (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))"
using f2 by blast
moreover
{ assume "(if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) ≠ (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))))"
moreover
{ assume "(if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) ≠ ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))"
then have "(if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) = (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ⟶ get_operand_w5 (snd instr ! 3) = 0"
by (metis f11 f16 f8) }
ultimately have "(if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) = (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ⟶ get_operand_w5 (snd instr ! 3) = 0"
by fastforce }
ultimately have "fst instr = arith_type UMULcc ∧ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) = (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ⟶ get_operand_w5 (snd instr ! 3) = 0"
using f13 f7 f3 by fastforce }
moreover
{ assume "mul_instr_sub1 (arith_type UMULcc) (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))) ≠ mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))"
moreover
{ assume "(if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) ≠ ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))"
then have "(if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) = (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ⟶ get_operand_w5 (snd instr ! 3) = 0"
by (metis f11 f16 f8) }
ultimately have "fst instr = arith_type UMULcc ∧ (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) = (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1)) else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) ⟶ get_operand_w5 (snd instr ! 3) = 0"
by fastforce }
ultimately have "fst instr = arith_type UMULcc ⟶ get_operand_w5 (snd instr ! 3) = 0"
using f12 by fastforce }
moreover
{ assume "write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))) ≠ write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))"
then have "fst instr = arith_type UMULcc ⟶ get_operand_w5 (snd instr ! 3) = 0"
by presburger }
ultimately have "fst instr = arith_type UMULcc ⟶ get_operand_w5 (snd instr ! 3) = 0 ∨ get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))"
by force
moreover
{ assume "fst instr ≠ arith_type UMULcc"
{ assume "fst instr ≠ arith_type UMULcc ∧ low_equal (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))"
moreover
{ assume "fst instr ≠ arith_type UMULcc ∧ low_equal (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))) ∧ snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))) = snd (fst (mul_instr_sub1 (arith_type UMUL) (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))"
then have "(fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ fst instr ≠ arith_type UMUL ∧ fst instr ≠ arith_type UMULcc ∨ (get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∨ get_operand_w5 (snd instr ! 3) = 0"
using f2 by presburger }
ultimately have "fst instr ≠ arith_type UMULcc ∧ (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) ≠ ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) ∨ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ fst instr ≠ arith_type UMUL ∧ fst instr ≠ arith_type UMULcc ∨ (get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∨ get_operand_w5 (snd instr ! 3) = 0"
by fastforce }
then have "(get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∨ get_operand_w5 (snd instr ! 3) = 0"
using f16 f11 f9 f8 f7 f4 f3 f2 by force }
moreover
{ assume "get_operand_w5 (snd instr ! 3) = 0"
moreover
{ assume "(fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0"
moreover
{ assume "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ ¬ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
moreover
{ assume "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ≠ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))"
then have "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ arith_type UMUL ≠ arith_type UMULcc ∨ fst instr ≠ arith_type UMULcc ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0"
by fastforce
then have "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∨ fst instr ≠ arith_type UMULcc ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0"
by force }
ultimately have "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∨ ((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ ¬ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∨ fst instr ≠ arith_type UMULcc ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0"
by simp }
ultimately have "((fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0) ∧ ¬ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) = 0 then user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))) else ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))) ∨ fst instr ≠ arith_type UMULcc ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0 ∨ (get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∧ (get_operand_w5 (snd instr ! 3) ≠ 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))))"
by auto
then have "fst instr ≠ arith_type UMULcc ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc) ∧ get_operand_w5 (snd instr ! 3) = 0 ∨ (get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∧ (get_operand_w5 (snd instr ! 3) ≠ 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))))"
using f15 by presburger
then have "(get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∧ (get_operand_w5 (snd instr ! 3) ≠ 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))))"
using f14 f13 f12 f2 by force }
ultimately have "(get_operand_w5 (snd instr ! 3) = 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∧ (get_operand_w5 (snd instr ! 3) ≠ 0 ∨ (fst instr ≠ arith_type UMUL ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc ∨ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))))"
using f16 f14 f11 f9 f8 f4 f2 by fastforce }
ultimately have "(get_operand_w5 (snd instr ! 3) ≠ 0 ⟶ (fst instr = arith_type UMUL ⟶ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMULcc ⟶ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMUL ∧ fst instr ≠ arith_type UMULcc ⟶ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))))) ∧ (get_operand_w5 (snd instr ! 3) = 0 ⟶ (fst instr = arith_type UMUL ⟶ low_equal (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMUL) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr = arith_type UMULcc ⟶ low_equal (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (arith_type UMULcc) (ucast (word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))) ∧ (fst instr ≠ arith_type UMUL ∧ fst instr ≠ arith_type UMULcc ⟶ low_equal (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))::word64) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (mul_instr_sub1 (fst instr) (ucast (word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64)) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (write_cpu (ucast ((word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))::word64) >> 32)) Y (snd (fst (get_curr_win () s2))))))))))))))"
by blast
moreover from t1 have
‹t1 = snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) ≠ 0 then ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) else user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1))))))) (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * uint (get_operand2 (snd instr) s1))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s1))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))) * sint (get_operand2 (snd instr) s1))) >> 32)) Y (snd (fst (get_curr_win () s1)))))))))))›
by (simp add: mul_instr_def) (simp add: simpler_gets_def bind_def h1_def h2_def Let_def case_prod_unfold)
moreover from t2 have
‹t2 = snd (fst (mul_instr_sub1 (fst instr) (ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2)))) (snd (fst (write_reg (if get_operand_w5 (snd instr ! 3) ≠ 0 then ucast (if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) else user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2))))))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3)) (snd (fst (write_cpu (ucast ((if fst instr = arith_type UMUL ∨ fst instr = arith_type UMULcc then word_of_int (uint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * uint (get_operand2 (snd instr) s2))::word64 else word_of_int (sint (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))) * sint (get_operand2 (snd instr) s2))) >> 32)) Y (snd (fst (get_curr_win () s2)))))))))))›
by (simp add: mul_instr_def) (simp add: simpler_gets_def bind_def h1_def h2_def Let_def case_prod_unfold)
ultimately show ?thesis
by (simp add: mul_instr_def)
qed
lemma div_write_new_val_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (div_write_new_val i result temp_V s1)) ∧
t2 = snd (fst (div_write_new_val i result temp_V s2))"
shows "low_equal t1 t2"
proof (cases "(fst i) ∈ {arith_type UDIVcc,arith_type SDIVcc}")
case True
then show ?thesis using a1
apply (simp add: div_write_new_val_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (clarsimp simp add: cpu_reg_val_low_equal)
using write_cpu_low_equal by blast
next
case False
then show ?thesis using a1
apply (simp add: div_write_new_val_def)
by (simp add: return_def)
qed
lemma div_comp_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (div_comp instr rs1 rd operand2 s1)) ∧
t2 = snd (fst (div_comp instr rs1 rd operand2 s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: div_comp_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (clarsimp simp add: get_curr_win_low_equal)
proof -
assume a1: "low_equal s1 s2"
have f2: "∀s sa sb w wa wb sc. ¬ low_equal s sa ∨ sb ≠ snd (fst (write_reg w (wa::'a word) wb s)) ∨ sc ≠ snd (fst (write_reg w wa wb sa)) ∨ low_equal sb sc"
by (meson write_reg_low_equal)
have f3: "gets (λs. ucast (get_CWP (cpu_reg_val PSR s))::'a word) = get_curr_win ()"
by (simp add: get_curr_win_def)
then have "((ucast (get_CWP (cpu_reg_val PSR s1)), s1), False) = (fst (get_curr_win () s1), snd (get_curr_win () s1))"
by (metis (no_types) prod.collapse simpler_gets_def)
then have f4: "ucast (get_CWP (cpu_reg_val PSR s1)) = fst (fst (get_curr_win () s1)) ∧ s1 = snd (fst (get_curr_win () s1))"
by (metis prod.collapse prod.simps(1))
have "((ucast (get_CWP (cpu_reg_val PSR s2)), s2), False) = (fst (get_curr_win () s2), snd (get_curr_win () s2))"
using f3 by (metis (no_types) prod.collapse simpler_gets_def)
then have f5: "ucast (get_CWP (cpu_reg_val PSR s2)) = fst (fst (get_curr_win () s2)) ∧ s2 = snd (fst (get_curr_win () s2))"
by (metis (no_types) prod.collapse prod.simps(1))
then have f6: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using f4 a1 by presburger
have f7: "∀s sa sb p w wa sc. ¬ low_equal (s::'a sparc_state) sa ∨ sb ≠ snd (fst (div_write_new_val p w wa s)) ∨ sc ≠ snd (fst (div_write_new_val p w wa sa)) ∨ low_equal sb sc"
by (meson div_write_new_val_low_equal)
have f8: "cpu_reg_val PSR s2 = cpu_reg_val PSR s1"
using a1 by (simp add: cpu_reg_val_def low_equal_def)
then have "fst (fst (get_curr_win () s2)) = ucast (get_CWP (cpu_reg_val PSR s1))"
using f5 by presburger
then have f9: "fst (fst (get_curr_win () s2)) = fst (fst (get_curr_win () s1))"
using f4 by presburger
have f10: "fst (fst (get_curr_win () s1)) = fst (fst (get_curr_win () s2))"
using f8 f5 f4 by presburger
have f11: "(word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))::word64) = word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))"
using f5 f4 a1 by (metis (no_types) cpu_reg_val_def low_equal_def user_reg_val_low_equal)
have f12: "ucast (get_CWP (cpu_reg_val PSR s1)) = fst (fst (get_curr_win () s2))"
using f8 f5 by presburger
then have "rd = 0 ⟶ (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) = user_reg_val (ucast (get_CWP (cpu_reg_val PSR s1))) 0 (snd (fst (get_curr_win () s1)))"
using f6 user_reg_val_low_equal by fastforce
then have f13: "rd = 0 ⟶ write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) 0 (snd (fst (get_curr_win () s1))) = write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1)))"
using f12 f10 by presburger
have f14: "write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) rd (snd (fst (get_curr_win () s2))) = write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))"
using f12 f11 by auto
have "write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) rd (snd (fst (get_curr_win () s1))) = write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))) ∧ write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) rd (snd (fst (get_curr_win () s2))) = write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) ⟶ low_equal (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))))))"
using f6 f2 by metis
moreover
{ assume "low_equal (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))))))"
then have "low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))"
using f11 f9 f7 by metis
moreover
{ assume "low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))))))))) ≠ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))"
then have "div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2) = (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) ⟶ rd = 0"
by fastforce }
ultimately have "div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2) = (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) ⟶ rd = 0 ∨ (rd ≠ 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))) ∧ (rd = 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))))"
by fastforce }
moreover
{ assume "write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) rd (snd (fst (get_curr_win () s1))) ≠ write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1)))"
then have "div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2) ≠ (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2))"
using f12 f9 by fastforce }
moreover
{ assume "write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (ucast (get_CWP (cpu_reg_val PSR s1))) rd (snd (fst (get_curr_win () s2))) ≠ write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))"
then have "rd = 0"
using f14 by presburger }
moreover
{ assume "rd = 0"
then have "rd = 0 ∧ low_equal (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))))))"
using f13 f12 f6 f2 by metis
then have "rd = 0 ∧ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s1))) rd (snd (fst (get_curr_win () s1))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s1))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (if rd = 0 then user_reg_val (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2))) else div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))"
using f11 f9 f7 by metis
then have "(rd ≠ 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))) ∧ (rd = 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))))"
using f10 by fastforce }
ultimately show "(rd ≠ 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (fst (fst (get_curr_win () s2))) rd (snd (fst (get_curr_win () s2)))))))))) ∧ (rd = 0 ⟶ low_equal (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s1))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s1))))))))) (snd (fst (div_write_new_val instr (div_comp_result instr (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2)) (div_comp_temp_V instr (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 32)) (ucast (div_comp_temp_64bit instr (word_cat (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (user_reg_val (fst (fst (get_curr_win () s2))) rs1 (snd (fst (get_curr_win () s2))))) operand2 >> 31))) (snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0 (snd (fst (get_curr_win () s2))))))))))"
using f9 by fastforce
qed
lemma div_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (div_instr instr s1)) ∧ t2 = snd (fst (div_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: div_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: return_def)
apply (auto simp add: get_operand2_low_equal)
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (auto simp add: traps_low_equal)
apply (blast intro: mod_trap_low_equal)
using div_comp_low_equal by blast
lemma get_curr_win_traps_low_equal:
assumes a1: "low_equal s1 s2"
shows "low_equal
(snd (fst (get_curr_win () s1))
⦇traps := insert some_trap (traps (snd (fst (get_curr_win () s1))))⦈)
(snd (fst (get_curr_win () s2))
⦇traps := insert some_trap (traps (snd (fst (get_curr_win () s2))))⦈)"
proof -
from a1 have f1: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by auto
then have f2: "(traps (snd (fst (get_curr_win () s1)))) =
(traps (snd (fst (get_curr_win () s2))))"
using traps_low_equal by auto
then show ?thesis using f1 f2 mod_trap_low_equal
by fastforce
qed
lemma save_restore_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (save_retore_sub1 result new_cwp rd s1)) ∧
t2 = snd (fst (save_retore_sub1 result new_cwp rd s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: save_retore_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (auto simp add: cpu_reg_val_low_equal)
using write_cpu_low_equal write_reg_low_equal
by fastforce
lemma get_WIM_bit_low_equal:
‹get_WIM_bit (nat ((uint (fst (fst (get_curr_win () s1))) - 1) mod NWINDOWS))
(cpu_reg_val WIM (snd (fst (get_curr_win () s1)))) =
get_WIM_bit (nat ((uint (fst (fst (get_curr_win () s2))) - 1) mod NWINDOWS))
(cpu_reg_val WIM (snd (fst (get_curr_win () s2))))›
if ‹low_equal s1 s2›
proof -
from that have f1: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by blast
then have f2: "(cpu_reg_val WIM (snd (fst (get_curr_win () s1)))) =
(cpu_reg_val WIM (snd (fst (get_curr_win () s2))))"
using cpu_reg_val_low_equal by auto
from that have "(fst (fst (get_curr_win () s1))) = (fst (fst (get_curr_win () s2)))"
using get_curr_win_low_equal by auto
then show ?thesis using f1 f2
by auto
qed
lemma get_WIM_bit_low_equal2:
‹get_WIM_bit (nat ((uint (fst (fst (get_curr_win () s1))) + 1) mod NWINDOWS))
(cpu_reg_val WIM (snd (fst (get_curr_win () s1)))) =
get_WIM_bit (nat ((uint (fst (fst (get_curr_win () s2))) + 1) mod NWINDOWS))
(cpu_reg_val WIM (snd (fst (get_curr_win () s2))))›
if ‹low_equal s1 s2›
proof -
from that have f1: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by blast
then have f2: "(cpu_reg_val WIM (snd (fst (get_curr_win () s1)))) =
(cpu_reg_val WIM (snd (fst (get_curr_win () s2))))"
using cpu_reg_val_low_equal by auto
from that have "(fst (fst (get_curr_win () s1))) = (fst (fst (get_curr_win () s2)))"
using get_curr_win_low_equal by auto
then show ?thesis using f1 f2
by auto
qed
lemma take_bit_5_mod_NWINDOWS_eq [simp]:
‹take_bit 5 (k mod NWINDOWS) = k mod NWINDOWS›
by (simp add: NWINDOWS_def take_bit_eq_mod)
lemma save_restore_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (save_restore_instr instr s1)) ∧ t2 = snd (fst (save_restore_instr instr s2))"
shows "low_equal t1 t2"
proof (cases "fst instr = ctrl_type SAVE")
case True
then have f1: "fst instr = ctrl_type SAVE" by auto
then show ?thesis using a1
apply (simp add: save_restore_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (simp add: get_curr_win_traps_low_equal)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: get_WIM_bit_low_equal)
apply (simp add: get_WIM_bit_low_equal)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: get_curr_win_low_equal)
using get_curr_win2_low_equal save_restore_instr_sub1_low_equal get_addr2_low_equal
apply metis
done
next
case False
then show ?thesis using a1
apply (simp add: save_restore_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (simp add: get_curr_win_traps_low_equal)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: get_WIM_bit_low_equal2)
apply (simp add: get_WIM_bit_low_equal2)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: get_curr_win_low_equal)
using get_curr_win2_low_equal save_restore_instr_sub1_low_equal get_addr2_low_equal
by metis
qed
lemma call_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (call_instr instr s1)) ∧ t2 = snd (fst (call_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: call_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (auto simp add: get_curr_win_low_equal)
using cpu_reg_val_low_equal get_curr_win2_low_equal
write_cpu_low_equal write_reg_low_equal
proof -
assume a1: "low_equal s1 s2"
assume "t1 = snd (fst (write_cpu (cpu_reg_val PC (snd (fst (get_curr_win () s1))) + (ucast (get_operand_w30 (snd instr ! 0)) << 2)) nPC (snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (get_curr_win () s1)))) PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 15 (snd (fst (get_curr_win () s1)))))))))))"
assume "t2 = snd (fst (write_cpu (cpu_reg_val PC (snd (fst (get_curr_win () s2))) + (ucast (get_operand_w30 (snd instr ! 0)) << 2)) nPC (snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (get_curr_win () s2)))) PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 15 (snd (fst (get_curr_win () s2)))))))))))"
have "∀c. cpu_reg_val c (snd (fst (get_curr_win () s1))) = cpu_reg_val c (snd (fst (get_curr_win () s2)))"
using a1 by (meson cpu_reg_val_low_equal get_curr_win2_low_equal)
then show "low_equal (snd (fst (write_cpu (cpu_reg_val PC (snd (fst (get_curr_win () s1))) + (ucast (get_operand_w30 (snd instr ! 0)) << 2)) nPC (snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (get_curr_win () s1)))) PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 15 (snd (fst (get_curr_win () s1)))))))))))) (snd (fst (write_cpu (cpu_reg_val PC (snd (fst (get_curr_win () s2))) + (ucast (get_operand_w30 (snd instr ! 0)) << 2)) nPC (snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (get_curr_win () s2)))) PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 15 (snd (fst (get_curr_win () s2))))))))))))"
using a1 by (metis (no_types) get_curr_win2_low_equal write_cpu_low_equal write_reg_low_equal)
qed
lemma jmpl_instr_low_equal_sub1:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (write_cpu (get_addr (snd instr) (snd (fst (get_curr_win () s2)))) nPC
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))))
PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))))))) ∧
t2 = snd (fst (write_cpu (get_addr (snd instr) (snd (fst (get_curr_win () s2)))) nPC
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))))
PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))))))))"
shows "low_equal t1 t2"
proof -
from a1 have f1: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by blast
then have f2: "(cpu_reg_val PC (snd (fst (get_curr_win () s1)))) =
(cpu_reg_val PC (snd (fst (get_curr_win () s2))))"
using cpu_reg_val_low_equal by blast
then have f3: "low_equal
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2))))))"
using f1 write_reg_low_equal by fastforce
then have "(cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1))))))) =
(cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))))"
using cpu_reg_val_low_equal by auto
then have f4: "low_equal
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))))
PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s1))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s1)))))))))
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))))
PC (snd (fst (write_reg (cpu_reg_val PC (snd (fst (get_curr_win () s2))))
(fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! 3))
(snd (fst (get_curr_win () s2)))))))))"
using f3 write_cpu_low_equal by fastforce
then show ?thesis using write_cpu_low_equal
using assms by blast
qed
lemma jmpl_instr_low_equal_sub2:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (write_cpu (get_addr (snd instr) (snd (fst (get_curr_win () s2)))) nPC
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))) PC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))))))) ∧
t2 = snd (fst (write_cpu (get_addr (snd instr) (snd (fst (get_curr_win () s2)))) nPC
(snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))))) PC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))))))))))"
shows "low_equal t1 t2"
proof -
from a1 have f1: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by blast
then have f2: "(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) =
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))"
using user_reg_val_low_equal by blast
then have f3: "low_equal
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))
(snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))))"
using f1 write_reg_low_equal by fastforce
then have "(cpu_reg_val nPC
(snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))) =
(cpu_reg_val nPC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))))))"
using cpu_reg_val_low_equal by blast
then have "low_equal
(snd (fst (write_cpu (cpu_reg_val nPC
(snd (fst (write_reg (user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1))))))) PC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s1)))))))))
(snd (fst (write_cpu (cpu_reg_val nPC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2))))))) PC (snd (fst (write_reg
(user_reg_val (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) 0
(snd (fst (get_curr_win () s2)))))))))"
using f1 f2 f3 write_cpu_low_equal by fastforce
then show ?thesis
using write_cpu_low_equal
using assms by blast
qed
lemma jmpl_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (jmpl_instr instr s1)) ∧ t2 = snd (fst (jmpl_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: jmpl_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply auto
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (simp add: get_curr_win_traps_low_equal)
apply (simp add: get_addr2_low_equal)
apply (simp add: get_addr2_low_equal)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp_all add: get_addr2_low_equal)
apply (simp_all add: get_curr_win_low_equal)
apply (case_tac "get_operand_w5 (snd instr ! 3) ≠ 0")
apply auto
using jmpl_instr_low_equal_sub1 apply blast
apply (simp_all add: get_curr_win_low_equal)
using jmpl_instr_low_equal_sub2 by blast
lemma rett_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
¬ snd (rett_instr instr s1) ∧
¬ snd (rett_instr instr s2) ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
t1 = snd (fst (rett_instr instr s1)) ∧ t2 = snd (fst (rett_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: rett_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply auto
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (simp add: return_def)
using mod_trap_low_equal traps_low_equal apply fastforce
using cpu_reg_val_low_equal apply fastforce
using cpu_reg_val_low_equal apply fastforce
apply (simp add: bind_def h1_def h2_def Let_def)
by (simp add: case_prod_unfold fail_def)
lemma read_state_reg_low_equal:
assumes a1: "low_equal s1 s2 ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
t1 = snd (fst (read_state_reg_instr instr s1)) ∧
t2 = snd (fst (read_state_reg_instr instr s2))"
shows "low_equal t1 t2"
proof (cases "(fst instr ∈ {sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR} ∨
(fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 ((snd instr)!0))))")
case True
then have "(fst instr ∈ {sreg_type RDPSR,sreg_type RDWIM,sreg_type RDTBR} ∨
(fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 ((snd instr)!0))))
∧ (((get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s1))))))::word1) = 0
∧ (((get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2))))))::word1) = 0"
by (metis assms get_curr_win_privilege)
then show ?thesis using a1
apply (simp add: read_state_reg_instr_def)
apply (simp add: Let_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply clarsimp
using get_curr_win_traps_low_equal
by auto
next
case False
then have f1: "¬((fst instr = sreg_type RDPSR ∨
fst instr = sreg_type RDWIM ∨
fst instr = sreg_type RDTBR ∨
fst instr = sreg_type RDASR ∧ privileged_ASR (get_operand_w5 (snd instr ! 0))))"
by blast
then show ?thesis
proof (cases "illegal_instruction_ASR (get_operand_w5 ((snd instr)!0))")
case True
then show ?thesis using a1 f1
apply read_state_reg_instr_privilege_proof
by (simp add: illegal_instruction_ASR_def)
next
case False
then have f2: "¬(illegal_instruction_ASR (get_operand_w5 ((snd instr)!0)))"
by auto
then show ?thesis
proof (cases "(get_operand_w5 ((snd instr)!1)) ≠ 0")
case True
then have f3: "(get_operand_w5 ((snd instr)!1)) ≠ 0"
by auto
then show ?thesis
proof (cases "fst instr = sreg_type RDY")
case True
then show ?thesis using a1 f1 f2 f3
apply (simp add: read_state_reg_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (auto simp add: get_curr_win_low_equal)
using cpu_reg_val_low_equal get_curr_win2_low_equal write_reg_low_equal
proof -
assume "low_equal s1 s2"
then have "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
by (meson get_curr_win2_low_equal)
then show "low_equal (snd (fst (write_reg (cpu_reg_val Y (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (cpu_reg_val Y (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))))))"
using cpu_reg_val_low_equal write_reg_low_equal by fastforce
qed
next
case False
then have f4: "¬(fst instr = sreg_type RDY)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type RDASR")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply read_state_reg_instr_privilege_proof
apply (clarsimp simp add: get_curr_win_low_equal)
using cpu_reg_val_low_equal get_curr_win2_low_equal write_reg_low_equal
proof -
assume a1: "low_equal s1 s2"
then have "cpu_reg_val (ASR (get_operand_w5 (snd instr ! 0))) (snd (fst (get_curr_win () s1))) = cpu_reg_val (ASR (get_operand_w5 (snd instr ! 0))) (snd (fst (get_curr_win () s2)))"
by (meson cpu_reg_val_low_equal get_curr_win2_low_equal)
then show "low_equal (snd (fst (write_reg (cpu_reg_val (ASR (get_operand_w5 (snd instr ! 0))) (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (cpu_reg_val (ASR (get_operand_w5 (snd instr ! 0))) (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))))))"
using a1 by (metis (no_types) get_curr_win2_low_equal write_reg_low_equal)
qed
next
case False
then have f5: "¬(fst instr = sreg_type RDASR)" by auto
then show ?thesis using a1 f1 f2 f3 f4 f5
apply read_state_reg_instr_privilege_proof
apply (clarsimp simp add: get_curr_win_low_equal)
using cpu_reg_val_low_equal get_curr_win2_low_equal write_reg_low_equal
proof -
assume a1: "low_equal s1 s2"
assume a2: "t1 = snd (fst (write_reg (cpu_reg_val TBR (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))))"
assume "t2 = snd (fst (write_reg (cpu_reg_val TBR (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2)))))"
have "∀s. ¬ low_equal (snd (fst (get_curr_win () s1))) s ∨ snd (fst (write_reg (cpu_reg_val TBR s) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))))) = t1"
using a2 by (simp add: cpu_reg_val_low_equal)
then show "low_equal (snd (fst (write_reg (cpu_reg_val TBR (snd (fst (get_curr_win () s1)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1)))))) (snd (fst (write_reg (cpu_reg_val TBR (snd (fst (get_curr_win () s2)))) (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))))))"
using a2 a1 by (metis (no_types) get_curr_win2_low_equal write_reg_low_equal)
qed
qed
qed
next
case False
then show ?thesis using a1 f1 f2
apply (simp add: read_state_reg_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def)
apply clarsimp
apply (simp add: case_prod_unfold)
using get_curr_win2_low_equal by auto
qed
qed
qed
lemma get_s_get_curr_win:
assumes a1: "low_equal s1 s2"
shows "get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))) =
get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2))))"
proof -
from a1 have "low_equal (snd (fst (get_curr_win () s1)))
(snd (fst (get_curr_win () s2)))"
using get_curr_win2_low_equal by blast
then show ?thesis
using cpu_reg_val_low_equal
by fastforce
qed
lemma write_state_reg_low_equal:
assumes a1: "low_equal s1 s2 ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
t1 = snd (fst (write_state_reg_instr instr s1)) ∧
t2 = snd (fst (write_state_reg_instr instr s2))"
shows "low_equal t1 t2"
proof (cases "fst instr = sreg_type WRY")
case True
then show ?thesis using a1
apply write_state_reg_instr_privilege_proof
apply (simp add: simpler_modify_def)
apply (simp add: delayed_pool_add_def DELAYNUM_def)
apply (auto simp add: get_curr_win_low_equal)
using get_curr_win2_low_equal cpu_reg_mod_low_equal
user_reg_val_low_equal get_operand2_low_equal
proof -
assume a1: "low_equal s1 s2"
assume "t2 = cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s2)))) Y (snd (fst (get_curr_win () s2)))"
assume "t1 = cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s1)))) Y (snd (fst (get_curr_win () s1)))"
have f2: "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using a1 by (meson get_curr_win2_low_equal)
then have f3: "⋀w wa. user_reg_val w wa (snd (fst (get_curr_win () s2))) = user_reg_val w wa (snd (fst (get_curr_win () s1)))"
by (simp add: user_reg_val_low_equal)
have "⋀is. get_operand2 is (snd (fst (get_curr_win () s2))) = get_operand2 is (snd (fst (get_curr_win () s1)))"
using f2 by (simp add: get_operand2_low_equal)
then show "low_equal (cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s1)))) Y (snd (fst (get_curr_win () s1)))) (cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s2)))) Y (snd (fst (get_curr_win () s2))))"
using f3 f2 by (metis cpu_reg_mod_low_equal)
qed
next
case False
then have f1: "¬(fst instr = sreg_type WRY)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type WRASR")
case True
then have f1_1: "fst instr = sreg_type WRASR" by auto
then show ?thesis
proof (cases "privileged_ASR (get_operand_w5 (snd instr ! 3)) ∧
get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))) = 0")
case True
then show ?thesis using a1 f1 f1_1
apply write_state_reg_instr_privilege_proof
apply (clarsimp simp add: get_s_get_curr_win)
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
by fastforce
next
case False
then have f1_2: "¬ (privileged_ASR (get_operand_w5 (snd instr ! 3)) ∧
get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))) = 0)"
by auto
then show ?thesis
proof (cases "illegal_instruction_ASR (get_operand_w5 (snd instr ! 3))")
case True
then show ?thesis using a1 f1 f1_1 f1_2
apply write_state_reg_instr_privilege_proof
apply (clarsimp simp add: get_s_get_curr_win)
apply auto
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
apply fastforce
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
by fastforce
next
case False
then show ?thesis using a1 f1 f1_1 f1_2
apply write_state_reg_instr_privilege_proof
apply (clarsimp simp add: get_s_get_curr_win)
apply auto
apply (simp add: simpler_modify_def)
apply (simp add: delayed_pool_add_def DELAYNUM_def)
apply (auto simp add: get_curr_win_low_equal)
using get_curr_win2_low_equal cpu_reg_mod_low_equal
user_reg_val_low_equal get_operand2_low_equal
proof -
assume a1: "low_equal s1 s2"
assume "t2 = cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s2)))) (ASR (get_operand_w5 (snd instr ! 3))) (snd (fst (get_curr_win () s2)))"
assume "t1 = cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s1)))) (ASR (get_operand_w5 (snd instr ! 3))) (snd (fst (get_curr_win () s1)))"
have "low_equal (snd (fst (get_curr_win () s1))) (snd (fst (get_curr_win () s2)))"
using a1 by (meson get_curr_win2_low_equal)
then show "low_equal (cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s1))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s1)))) (ASR (get_operand_w5 (snd instr ! 3))) (snd (fst (get_curr_win () s1)))) (cpu_reg_mod (user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0)) (snd (fst (get_curr_win () s2))) XOR get_operand2 (snd instr) (snd (fst (get_curr_win () s2)))) (ASR (get_operand_w5 (snd instr ! 3))) (snd (fst (get_curr_win () s2))))"
using cpu_reg_mod_low_equal get_operand2_low_equal user_reg_val_low_equal by fastforce
next
assume f1: "¬ illegal_instruction_ASR (get_operand_w5 (snd instr ! 3))"
assume f2: "fst instr = sreg_type WRASR"
assume f3: "snd (fst (write_state_reg_instr instr s1)) =
snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s1))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s1))))) "
assume f4: "snd (fst (write_state_reg_instr instr s2)) =
snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s2))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s2)))))"
assume f5: "low_equal s1 s2"
assume f6: "(get_S (cpu_reg_val PSR s1)) = 0"
assume f7: "(get_S (cpu_reg_val PSR s2)) = 0"
assume f8: "t1 = snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s1))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s1)))))"
assume f9: "t2 = snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s2))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s2)))))"
assume f10: "get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))) ≠ 0"
assume f11: "(⋀s1 s2 t1 t2.
low_equal s1 s2 ⟹
t1 = snd (fst (get_curr_win () s1)) ⟹ t2 = snd (fst (get_curr_win () s2)) ⟹ low_equal t1 t2)"
assume f12: "(⋀s1 s2 t1 w cr t2.
low_equal s1 s2 ∧ t1 = cpu_reg_mod w cr s1 ∧ t2 = cpu_reg_mod w cr s2 ⟹ low_equal t1 t2)"
assume f13: "(⋀s1 s2 win ur. low_equal s1 s2 ⟹ user_reg_val win ur s1 = user_reg_val win ur s2)"
assume f14: "(⋀s1 s2 op_list. low_equal s1 s2 ⟹ get_operand2 op_list s1 = get_operand2 op_list s2)"
show "low_equal
(snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s1))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s1))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s1))))))
(snd (fst (modify
(delayed_pool_add
(DELAYNUM,
user_reg_val (fst (fst (get_curr_win () s2))) (get_operand_w5 (snd instr ! Suc 0))
(snd (fst (get_curr_win () s2))) XOR
get_operand2 (snd instr) (snd (fst (get_curr_win () s2))),
ASR (get_operand_w5 (snd instr ! 3))))
(snd (fst (get_curr_win () s2))))))"
using f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14
using Sparc_Properties.ucast_0 assms get_curr_win_privilege by blast
qed
qed
qed
next
case False
then have f2: "¬(fst instr = sreg_type WRASR)" by auto
have f3: "get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s1)))) = 0 ∧
get_S (cpu_reg_val PSR (snd (fst (get_curr_win () s2)))) = 0"
using get_curr_win_privilege a1 by (metis ucast_id)
then show ?thesis
proof (cases "fst instr = sreg_type WRPSR")
case True
then show ?thesis using a1 f1 f2 f3
apply write_state_reg_instr_privilege_proof
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
by fastforce
next
case False
then have f4: "¬(fst instr = sreg_type WRPSR)" by auto
then show ?thesis
proof (cases "fst instr = sreg_type WRWIM")
case True
then show ?thesis using a1 f1 f2 f3 f4
apply write_state_reg_instr_privilege_proof
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
by fastforce
next
case False
then have f5: "¬(fst instr = sreg_type WRWIM)" by auto
then show ?thesis using a1 f1 f2 f3 f4 f5
apply write_state_reg_instr_privilege_proof
apply (simp add: raise_trap_def add_trap_set_def simpler_modify_def)
apply (clarsimp simp add: get_curr_win3_low_equal)
using traps_low_equal mod_trap_low_equal get_curr_win2_low_equal
by fastforce
qed
qed
qed
qed
lemma flush_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (flush_instr instr s1)) ∧
t2 = snd (fst (flush_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: flush_instr_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def simpler_modify_def)
apply (simp add: flush_cache_all_def)
apply (simp add: low_equal_def)
apply (simp add: user_accessible_def)
apply (simp add: mem_equal_def)
by auto
lemma branch_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2"
shows "branch_instr_sub1 instr_name s1 = branch_instr_sub1 instr_name s2"
using a1 apply (simp add: branch_instr_sub1_def)
by (simp add: low_equal_def)
lemma set_annul_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (set_annul True s1)) ∧
t2 = snd (fst (set_annul True s2))"
shows "low_equal t1 t2"
using a1 apply (simp add: set_annul_def)
apply (simp add: simpler_modify_def annul_mod_def)
using state_var2_low_equal state_var_low_equal
by fastforce
lemma branch_instr_low_equal_sub0:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (write_cpu (cpu_reg_val PC s2 +
sign_ext24 (ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1))))) ∧
t2 = snd (fst (write_cpu (cpu_reg_val PC s2 +
sign_ext24 (ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2)))))"
shows "low_equal t1 t2"
proof -
from a1 have "low_equal
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1)))
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2)))"
using write_cpu_low_equal by blast
then show ?thesis
using a1 write_cpu_low_equal by blast
qed
lemma branch_instr_low_equal_sub1:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (set_annul True (snd (fst (write_cpu
(cpu_reg_val PC s2 + sign_ext24
(ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1)))))))) ∧
t2 = snd (fst (set_annul True (snd (fst (write_cpu
(cpu_reg_val PC s2 + sign_ext24
(ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2))))))))"
shows "low_equal t1 t2"
proof -
from a1 have "low_equal
(snd (fst (write_cpu
(cpu_reg_val PC s2 + sign_ext24
(ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1))))))
(snd (fst (write_cpu
(cpu_reg_val PC s2 + sign_ext24
(ucast (get_operand_w22 (snd instr ! Suc 0)) << 2))
nPC (snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2))))))"
using branch_instr_low_equal_sub0 by blast
then show ?thesis using a1
using set_annul_low_equal by blast
qed
lemma branch_instr_low_equal_sub2:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (set_annul True
(snd (fst (write_cpu (cpu_reg_val nPC s2 + 4) nPC
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1)))))))) ∧
t2 = snd (fst (set_annul True
(snd (fst (write_cpu (cpu_reg_val nPC s2 + 4) nPC
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2))))))))"
shows "low_equal t1 t2"
proof -
from a1 have "low_equal
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1)))
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2)))"
using write_cpu_low_equal by blast
then have "low_equal
(snd (fst (write_cpu (cpu_reg_val nPC s2 + 4) nPC
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s1))))))
(snd (fst (write_cpu (cpu_reg_val nPC s2 + 4) nPC
(snd (fst (write_cpu (cpu_reg_val nPC s2) PC s2))))))"
using write_cpu_low_equal by blast
then show ?thesis using a1
using set_annul_low_equal by blast
qed
lemma branch_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
t1 = snd (fst (branch_instr instr s1)) ∧
t2 = snd (fst (branch_instr instr s2))"
shows "low_equal t1 t2"
using a1
apply (simp add: branch_instr_def)
apply (simp add: Let_def simpler_gets_def bind_def h1_def h2_def)
apply (simp add: case_prod_unfold return_def)
apply clarsimp
apply (simp add: branch_instr_sub1_low_equal)
apply (simp_all add: cpu_reg_val_low_equal)
apply (cases "branch_instr_sub1 (fst instr) s2 = 1")
apply clarsimp
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp_all add: cpu_reg_val_low_equal)
apply (simp add: case_prod_unfold)
apply (cases "fst instr = bicc_type BA ∧ get_operand_flag (snd instr ! 0) = 1")
apply clarsimp
using branch_instr_low_equal_sub1 apply blast
apply clarsimp
apply (simp add: return_def)
using branch_instr_low_equal_sub0 apply fastforce
apply (simp add: bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (cases "get_operand_flag (snd instr ! 0) = 1")
apply clarsimp
apply (simp_all add: cpu_reg_val_low_equal)
using branch_instr_low_equal_sub2 apply metis
apply (simp add: return_def)
using write_cpu_low_equal by metis
lemma dispath_instr_low_equal:
assumes a1: "low_equal s1 s2 ∧
(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
¬ snd (dispatch_instruction instr s1) ∧
¬ snd (dispatch_instruction instr s2) ∧
t1 = (snd (fst (dispatch_instruction instr s1))) ∧
t2 = (snd (fst (dispatch_instruction instr s2)))"
shows "low_equal t1 t2"
proof (cases "get_trap_set s1 = {}")
case True
then have f_no_traps: "get_trap_set s1 = {} ∧ get_trap_set s2 = {}"
using a1 by (simp add: low_equal_def get_trap_set_def)
then show ?thesis
proof (cases "fst instr ∈ {load_store_type LDSB,load_store_type LDUB,
load_store_type LDUBA,load_store_type LDUH,load_store_type LD,
load_store_type LDA,load_store_type LDD}")
case True
then show ?thesis using a1 f_no_traps
apply dispath_instr_privilege_proof
by (blast intro: load_instr_low_equal)
next
case False
then have f1: "fst instr ∉ {load_store_type LDSB, load_store_type LDUB,
load_store_type LDUBA, load_store_type LDUH,
load_store_type LD, load_store_type LDA, load_store_type LDD}"
by auto
then show ?thesis
proof (cases "fst instr ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD}")
case True
then show ?thesis using a1 f_no_traps f1
apply dispath_instr_privilege_proof
using store_instr_low_equal by blast
next
case False
then have f2: "¬(fst instr ∈ {load_store_type STB,load_store_type STH,
load_store_type ST,load_store_type STA,load_store_type STD})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {sethi_type SETHI}")
case True
then show ?thesis using a1 f_no_traps f1 f2
apply dispath_instr_privilege_proof
by (auto intro: sethi_low_equal)
next
case False
then have f3: "¬(fst instr ∈ {sethi_type SETHI})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {nop_type NOP}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3
apply dispath_instr_privilege_proof
by (auto intro: nop_low_equal)
next
case False
then have f4: "¬(fst instr ∈ {nop_type NOP})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {logic_type ANDs,logic_type ANDcc,logic_type ANDN,
logic_type ANDNcc,logic_type ORs,logic_type ORcc,logic_type ORN,
logic_type XORs,logic_type XNOR}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4
apply dispath_instr_privilege_proof
using logical_instr_low_equal by blast
next
case False
then have f5: "¬(fst instr ∈ {logic_type ANDs,logic_type ANDcc,logic_type ANDN,
logic_type ANDNcc,logic_type ORs,logic_type ORcc,logic_type ORN,
logic_type XORs,logic_type XNOR})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {shift_type SLL,shift_type SRL,shift_type SRA}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5
apply dispath_instr_privilege_proof
using shift_instr_low_equal by blast
next
case False
then have f6: "¬(fst instr ∈ {shift_type SLL,shift_type SRL,shift_type SRA})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type ADD,arith_type ADDcc,arith_type ADDX}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6
apply dispath_instr_privilege_proof
using add_instr_low_equal by blast
next
case False
then have f7: "¬(fst instr ∈ {arith_type ADD,arith_type ADDcc,arith_type ADDX})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type SUB,arith_type SUBcc,arith_type SUBX}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7
apply dispath_instr_privilege_proof
using sub_instr_low_equal by blast
next
case False
then have f8: "¬(fst instr ∈ {arith_type SUB,arith_type SUBcc,arith_type SUBX})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type UMUL,arith_type SMUL,arith_type SMULcc}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8
apply dispath_instr_privilege_proof
using mul_instr_low_equal by blast
next
case False
then have f9: "¬(fst instr ∈ {arith_type UMUL,arith_type SMUL,
arith_type SMULcc})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {arith_type UDIV,arith_type UDIVcc,arith_type SDIV}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9
apply dispath_instr_privilege_proof
using div_instr_low_equal by blast
next
case False
then have f10: "¬(fst instr ∈ {arith_type UDIV,
arith_type UDIVcc,arith_type SDIV})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type SAVE,ctrl_type RESTORE}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
apply dispath_instr_privilege_proof
using save_restore_instr_low_equal by blast
next
case False
then have f11: "¬(fst instr ∈ {ctrl_type SAVE,ctrl_type RESTORE})"
by auto
then show ?thesis
proof (cases "fst instr ∈ {call_type CALL}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
apply dispath_instr_privilege_proof
using call_instr_low_equal by blast
next
case False
then have f12: "¬(fst instr ∈ {call_type CALL})" by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type JMPL}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12
apply dispath_instr_privilege_proof
using jmpl_instr_low_equal by blast
next
case False
then have f13: "¬(fst instr ∈ {ctrl_type JMPL})" by auto
then show ?thesis
proof (cases "fst instr ∈ {ctrl_type RETT}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
f11 f12 f13
apply dispath_instr_privilege_proof
using rett_instr_low_equal by blast
next
case False
then have f14: "¬(fst instr ∈ {ctrl_type RETT})" by auto
then show ?thesis
proof (cases "fst instr ∈ {sreg_type RDY,sreg_type RDPSR,
sreg_type RDWIM, sreg_type RDTBR}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9 f10
f11 f12 f13 f14
apply dispath_instr_privilege_proof
using read_state_reg_low_equal by blast
next
case False
then have f15: "¬(fst instr ∈ {sreg_type RDY,sreg_type RDPSR,
sreg_type RDWIM, sreg_type RDTBR})" by auto
then show ?thesis
proof (cases "fst instr ∈ {sreg_type WRY,sreg_type WRPSR,
sreg_type WRWIM, sreg_type WRTBR}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9
f10 f11 f12 f13 f14 f15
apply dispath_instr_privilege_proof
using write_state_reg_low_equal by blast
next
case False
then have f16: "¬(fst instr ∈ {sreg_type WRY,sreg_type WRPSR,
sreg_type WRWIM, sreg_type WRTBR})" by auto
then show ?thesis
proof (cases "fst instr ∈ {load_store_type FLUSH}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8 f9
f10 f11 f12 f13 f14 f15 f16
apply dispath_instr_privilege_proof
using flush_instr_low_equal by blast
next
case False
then have f17: "¬(fst instr ∈ {load_store_type FLUSH})" by auto
then show ?thesis
proof (cases "fst instr ∈ {bicc_type BE,bicc_type BNE,
bicc_type BGU,bicc_type BLE,bicc_type BL,bicc_type BGE,
bicc_type BNEG,bicc_type BG,bicc_type BCS,bicc_type BLEU,
bicc_type BCC,bicc_type BA,bicc_type BN}")
case True
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8
f9 f10 f11 f12 f13 f14 f15 f16 f17
apply dispath_instr_privilege_proof
using branch_instr_low_equal by blast
next
case False
then show ?thesis using a1 f_no_traps f1 f2 f3 f4 f5 f6 f7 f8
f9 f10 f11 f12 f13 f14 f15 f16 f17
apply dispath_instr_privilege_proof
by (simp add: fail_def)
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
qed
next
case False
then have "get_trap_set s1 ≠ {} ∧ get_trap_set s2 ≠ {}"
using a1 by (simp add: low_equal_def get_trap_set_def)
then show ?thesis using a1
apply (simp add: dispatch_instruction_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def)
apply (simp add: Let_def)
by (simp add: return_def)
qed
lemma execute_instr_sub1_low_equal:
assumes a1: "low_equal s1 s2 ∧
¬ snd (execute_instr_sub1 instr s1) ∧
¬ snd (execute_instr_sub1 instr s2) ∧
t1 = (snd (fst (execute_instr_sub1 instr s1))) ∧
t2 = (snd (fst (execute_instr_sub1 instr s2)))"
shows "low_equal t1 t2"
proof (cases "get_trap_set s1 = {}")
case True
then have "get_trap_set s1 = {} ∧ get_trap_set s2 = {}"
using a1 by (simp add: low_equal_def get_trap_set_def)
then show ?thesis using a1
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (case_tac "fst instr ≠ call_type CALL ∧
fst instr ≠ ctrl_type RETT ∧
fst instr ≠ ctrl_type JMPL ∧
fst instr ≠ bicc_type BE ∧
fst instr ≠ bicc_type BNE ∧
fst instr ≠ bicc_type BGU ∧
fst instr ≠ bicc_type BLE ∧
fst instr ≠ bicc_type BL ∧
fst instr ≠ bicc_type BGE ∧
fst instr ≠ bicc_type BNEG ∧
fst instr ≠ bicc_type BG ∧
fst instr ≠ bicc_type BCS ∧
fst instr ≠ bicc_type BLEU ∧
fst instr ≠ bicc_type BCC ∧
fst instr ≠ bicc_type BA ∧ fst instr ≠ bicc_type BN")
apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: low_equal_def)
apply (simp add: cpu_reg_val_def write_cpu_def cpu_reg_mod_def)
apply (simp add: simpler_modify_def return_def)
apply (simp add: user_accessible_mod_cpu_reg mem_equal_mod_cpu_reg)
apply clarsimp
by (auto simp add: return_def)
next
case False
then have "get_trap_set s1 ≠ {} ∧ get_trap_set s2 ≠ {}"
using a1 by (simp add: low_equal_def get_trap_set_def)
then show ?thesis using a1
apply (simp add: execute_instr_sub1_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: return_def)
qed
theorem non_interference_step:
assumes a1: "(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
good_context s1 ∧
get_delayed_pool s1 = [] ∧ get_trap_set s1 = {} ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
get_delayed_pool s2 = [] ∧ get_trap_set s2 = {} ∧
good_context s2 ∧
low_equal s1 s2"
shows "∃t1 t2. Some t1 = NEXT s1 ∧ Some t2 = NEXT s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧
low_equal t1 t2"
proof -
from a1 have "good_context s1 ∧ good_context s2" by auto
then have "NEXT s1 = Some (snd (fst (execute_instruction () s1))) ∧
NEXT s2 = Some (snd (fst (execute_instruction () s2)))"
by (simp add: single_step)
then have "∃t1 t2. Some t1 = NEXT s1 ∧ Some t2 = NEXT s2"
by auto
then have f0: "snd (execute_instruction() s1) = False ∧
snd (execute_instruction() s2) = False"
by (auto simp add: NEXT_def case_prod_unfold)
then have f1: "∃t1 t2. Some t1 = NEXT s1 ∧
Some t2 = NEXT s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0"
using a1
apply (auto simp add: NEXT_def case_prod_unfold)
by (auto simp add: safe_privilege)
then show ?thesis
proof (cases "exe_mode_val s1")
case True
then have f_exe0: "exe_mode_val s1" by auto
then have f_exe: "exe_mode_val s1 ∧ exe_mode_val s2"
proof -
have "low_equal s1 s2" using a1 by auto
then have "state_var s1 = state_var s2" by (simp add: low_equal_def)
then have "exe_mode_val s1 = exe_mode_val s2" by (simp add: exe_mode_val_def)
then show ?thesis using f_exe0 by auto
qed
then show ?thesis
proof (cases "∃e. fetch_instruction (delayed_pool_write s1) = Inl e")
case True
then have f_fetch_error: "∃e. fetch_instruction (delayed_pool_write s1) = Inl e" by auto
then have f_fetch_error2: "(∃e. fetch_instruction (delayed_pool_write s1) = Inl e) ∧
(∃e. fetch_instruction (delayed_pool_write s2) = Inl e)"
proof -
have "cpu_reg s1 = cpu_reg s2"
using a1 by (simp add: low_equal_def)
then have "cpu_reg_val PC s1 = cpu_reg_val PC s2"
by (simp add: cpu_reg_val_def)
then have "cpu_reg_val PC s1 = cpu_reg_val PC s2 ∧
(((get_S (cpu_reg_val PSR (delayed_pool_write s1))))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR (delayed_pool_write s2))))::word1) = 0"
using a1
by (auto simp add: empty_delayed_pool_write_privilege)
then show ?thesis using a1 f_fetch_error
apply (simp add: fetch_instruction_def)
apply (simp add: Let_def)
apply clarsimp
apply (case_tac "uint (3 AND cpu_reg_val PC (delayed_pool_write s1)) = 0")
apply auto
apply (case_tac "fst (memory_read 8 (cpu_reg_val PC (delayed_pool_write s1))
(delayed_pool_write s1)) = None")
apply auto
apply (simp add: case_prod_unfold)
using a1 apply (auto simp add: mem_read_delayed_write_low_equal)
apply (simp add: case_prod_unfold)
using a1 apply (auto simp add: mem_read_delayed_write_low_equal)
apply (simp add: delayed_pool_write_def)
by (simp add: Let_def get_delayed_write_def)
qed
then show ?thesis
proof (cases "exe_mode_val s1")
case True
then have "exe_mode_val s1 ∧ exe_mode_val s2" using exe_mode_low_equal a1 by auto
then show ?thesis using f1
apply (simp add: NEXT_def execute_instruction_def)
apply (simp add: bind_def h1_def h2_def Let_def simpler_gets_def)
using a1 apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
using f_fetch_error2 apply clarsimp
apply (simp add: raise_trap_def simpler_modify_def return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def simpler_modify_def)
apply (simp add: raise_trap_def simpler_modify_def return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: return_def)
apply (simp add: delayed_pool_write_def get_delayed_write_def Let_def)
apply (simp add: low_equal_def)
apply (simp add: add_trap_set_def)
apply (simp add: cpu_reg_val_def)
apply clarsimp
by (simp add: mem_equal_mod_trap user_accessible_mod_trap)
next
case False
then have "¬ (exe_mode_val s1) ∧ ¬ (exe_mode_val s2)"
using exe_mode_low_equal a1 by auto
then show ?thesis using f1
apply (simp add: NEXT_def execute_instruction_def)
apply (simp add: bind_def h1_def h2_def Let_def simpler_gets_def)
using a1 apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
by (simp add: return_def)
qed
next
case False
then have f_fetch_suc: "(∃v. fetch_instruction (delayed_pool_write s1) = Inr v)"
using fetch_instr_result_1 by auto
then have "(∃v. fetch_instruction (delayed_pool_write s1) = Inr v ∧
fetch_instruction (delayed_pool_write s2) = Inr v)"
proof -
have "cpu_reg s1 = cpu_reg s2"
using a1 by (simp add: low_equal_def)
then have "cpu_reg_val PC s1 = cpu_reg_val PC s2"
by (simp add: cpu_reg_val_def)
then have "cpu_reg_val PC s1 = cpu_reg_val PC s2 ∧
(((get_S (cpu_reg_val PSR (delayed_pool_write s1))))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR (delayed_pool_write s2))))::word1) = 0"
using a1
by (auto simp add: empty_delayed_pool_write_privilege)
then show ?thesis using a1 f_fetch_suc
apply (simp add: fetch_instruction_def)
apply (simp add: Let_def)
apply clarsimp
apply (case_tac "uint (3 AND cpu_reg_val PC (delayed_pool_write s1)) = 0")
apply auto
apply (case_tac "fst (memory_read 8 (cpu_reg_val PC (delayed_pool_write s1))
(delayed_pool_write s1)) = None")
apply auto
apply (simp add: case_prod_unfold)
using a1 apply (auto simp add: mem_read_delayed_write_low_equal)
apply (simp add: case_prod_unfold)
using a1 apply (auto simp add: mem_read_delayed_write_low_equal)
apply (simp add: delayed_pool_write_def)
by (simp add: Let_def get_delayed_write_def)
qed
then have "(∃v. fetch_instruction (delayed_pool_write s1) = Inr v ∧
fetch_instruction (delayed_pool_write s2) = Inr v ∧
¬ (∃e. (decode_instruction v) = Inl e))"
using dispatch_fail f0 a1 f_exe by auto
then have f_fetch_dec: "(∃v. fetch_instruction (delayed_pool_write s1) = Inr v ∧
fetch_instruction (delayed_pool_write s2) = Inr v ∧
(∃v1. (decode_instruction v) = Inr v1))"
using decode_instr_result_4 by auto
then show ?thesis
proof (cases "annul_val (delayed_pool_write s1)")
case True
then have "annul_val (delayed_pool_write s1) ∧ annul_val (delayed_pool_write s2)"
using a1
apply (simp add: low_equal_def)
by (simp add: delayed_pool_write_def get_delayed_write_def annul_val_def)
then show ?thesis using a1 f1 f_exe f_fetch_dec
apply (simp add: NEXT_def execute_instruction_def)
apply (simp add: exec_gets return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: write_cpu_def cpu_reg_val_def set_annul_def)
apply (simp add: simpler_modify_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: write_cpu_def cpu_reg_val_def set_annul_def)
apply (simp add: simpler_modify_def)
apply (simp add: cpu_reg_mod_def annul_mod_def)
apply (simp add: delayed_pool_write_def get_delayed_write_def)
apply (simp add: write_annul_def)
apply clarsimp
apply (simp add: low_equal_def)
apply (simp add: user_accessible_annul mem_equal_annul)
by (metis)
next
case False
then have "¬ annul_val (delayed_pool_write s1) ∧
¬ annul_val (delayed_pool_write s2)"
using a1 apply (simp add: low_equal_def)
apply (simp add: delayed_pool_write_def get_delayed_write_def)
by (simp add: annul_val_def)
then show ?thesis using a1 f1 f_exe f_fetch_dec
apply (simp add: NEXT_def execute_instruction_def)
apply (simp add: exec_gets return_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: simpler_modify_def)
apply clarsimp
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (case_tac "snd (execute_instr_sub1 (a, b)
(snd (fst (dispatch_instruction (a, b)
(delayed_pool_write s1))))) ∨
snd (dispatch_instruction (a, b) (delayed_pool_write s1))")
apply auto
apply (case_tac "snd (execute_instr_sub1 (a, b)
(snd (fst (dispatch_instruction (a, b)
(delayed_pool_write s2))))) ∨
snd (dispatch_instruction (a, b) (delayed_pool_write s2))")
apply auto
apply (simp add: simpler_modify_def)
apply (simp add: simpler_gets_def bind_def h1_def h2_def Let_def)
apply (simp add: case_prod_unfold)
apply (simp add: delayed_pool_write_def get_delayed_write_def)
by (meson dispath_instr_low_equal dispath_instr_privilege execute_instr_sub1_low_equal)
qed
qed
next
case False
then have f_non_exe: "exe_mode_val s1 = False" by auto
then have "exe_mode_val s1 = False ∧ exe_mode_val s2 = False"
proof -
have "low_equal s1 s2" using a1 by auto
then have "state_var s1 = state_var s2" by (simp add: low_equal_def)
then have "exe_mode_val s1 = exe_mode_val s2" by (simp add: exe_mode_val_def)
then show ?thesis using f_non_exe by auto
qed
then show ?thesis using f1 a1
apply (simp add: NEXT_def execute_instruction_def)
by (simp add: simpler_gets_def bind_def h1_def h2_def Let_def return_def)
qed
qed
function (sequential) SEQ:: "nat ⇒ ('a::len) sparc_state ⇒ ('a) sparc_state option"
where "SEQ 0 s = Some s"
|"SEQ n s = (
case SEQ (n-1) s of None ⇒ None
| Some t ⇒ NEXT t
)"
by pat_completeness auto
termination by lexicographic_order
lemma SEQ_suc: "SEQ n s = Some t ⟹ SEQ (Suc n) s = NEXT t"
apply (induction n)
apply clarsimp
by (simp add: option.case_eq_if)
definition user_seq_exe:: "nat ⇒ ('a::len) sparc_state ⇒ bool" where
"user_seq_exe n s ≡ ∀i t. (i ≤ n ∧ SEQ i s = Some t) ⟶
(good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {})"
text ‹NIA is short for non-interference assumption.›
definition "NIA t1 t2 ≡
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧
good_context t1 ∧ get_delayed_pool t1 = [] ∧ get_trap_set t1 = {} ∧
good_context t2 ∧ get_delayed_pool t2 = [] ∧ get_trap_set t2 = {} ∧
low_equal t1 t2"
text ‹NIC is short for non-interference conclusion.›
definition "NIC t1 t2 ≡ (∃u1 u2. Some u1 = NEXT t1 ∧ Some u2 = NEXT t2 ∧
(((get_S (cpu_reg_val PSR u1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR u2)))::word1) = 0 ∧
low_equal u1 u2)"
lemma NIS_short: "∀t1 t2. NIA t1 t2 ⟶ NIC t1 t2"
apply (simp add: NIA_def NIC_def)
using non_interference_step by auto
lemma non_interference_induct_case_sub1:
assumes a1: "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
NIA t1 t2))"
shows "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
NIA t1 t2 ∧
NIC t1 t2))"
using NIS_short
using assms by auto
lemma non_interference_induct_case:
assumes a1:
"((∀i t. i ≤ n ∧ SEQ i s1 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {}) ∧
(∀i t. i ≤ n ∧ SEQ i s2 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {}) ⟶
(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧ low_equal t1 t2))) ∧
(∀i t. i ≤ Suc n ∧ SEQ i s1 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {}) ∧
(∀i t. i ≤ Suc n ∧ SEQ i s2 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {})"
shows "∃t1. Some t1 = (case SEQ n s1 of None ⇒ None | Some x ⇒ NEXT x) ∧
(∃t2. Some t2 = (case SEQ n s2 of None ⇒ None | Some x ⇒ NEXT x) ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧ low_equal t1 t2)"
proof -
from a1 have f1: "((∀i t. i ≤ n ∧ SEQ i s1 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {}) ∧
(∀i t. i ≤ n ∧ SEQ i s2 = Some t ⟶
good_context t ∧ get_delayed_pool t = [] ∧ get_trap_set t = {}))"
by (metis le_SucI)
then have f2: "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧
low_equal t1 t2))"
using a1 by auto
then have f3: "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
NIA t1 t2))"
using f1 NIA_def by (metis (full_types) dual_order.refl)
then have "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
NIA t1 t2 ∧
NIC t1 t2))"
using non_interference_induct_case_sub1 by blast
then have "(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
((((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧
good_context t1 ∧ get_delayed_pool t1 = [] ∧ get_trap_set t1 = {} ∧
good_context t2 ∧ get_delayed_pool t2 = [] ∧ get_trap_set t2 = {} ∧
low_equal t1 t2) ∧
(∃u1 u2. Some u1 = NEXT t1 ∧ Some u2 = NEXT t2 ∧
(((get_S (cpu_reg_val PSR u1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR u2)))::word1) = 0 ∧
low_equal u1 u2)))"
using NIA_def NIC_def by fastforce
then show ?thesis
by (metis option.simps(5))
qed
lemma non_interference_induct_case_sub2:
assumes a1:
"(user_seq_exe n s1 ∧
user_seq_exe n s2 ⟶
(∃t1. Some t1 = SEQ n s1 ∧
(∃t2. Some t2 = SEQ n s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧ low_equal t1 t2))) ∧
user_seq_exe (Suc n) s1 ∧
user_seq_exe (Suc n) s2"
shows "∃t1. Some t1 = (case SEQ n s1 of None ⇒ None | Some x ⇒ NEXT x) ∧
(∃t2. Some t2 = (case SEQ n s2 of None ⇒ None | Some x ⇒ NEXT x) ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧ low_equal t1 t2)"
using a1
by (simp add: non_interference_induct_case user_seq_exe_def)
theorem non_interference:
assumes a1:
"(((get_S (cpu_reg_val PSR s1)))::word1) = 0 ∧
good_context s1 ∧
get_delayed_pool s1 = [] ∧ get_trap_set s1 = {} ∧
(((get_S (cpu_reg_val PSR s2)))::word1) = 0 ∧
get_delayed_pool s2 = [] ∧ get_trap_set s2 = {} ∧
good_context s2 ∧
user_seq_exe n s1 ∧ user_seq_exe n s2 ∧
low_equal s1 s2"
shows "(∃t1 t2. Some t1 = SEQ n s1 ∧ Some t2 = SEQ n s2 ∧
(((get_S (cpu_reg_val PSR t1)))::word1) = 0 ∧
(((get_S (cpu_reg_val PSR t2)))::word1) = 0 ∧
low_equal t1 t2)"
using a1
apply (induction n)
apply (simp add: user_seq_exe_def)
apply clarsimp
by (simp add: non_interference_induct_case_sub2)
end
Theory Sparc_Init_State
theory Sparc_Init_State
imports Main Sparc_State Sparc_Types Sparc_Execution
begin
definition emp_cpu_reg :: "cpu_context" where
"emp_cpu_reg r ≡ 0"
definition emp_user_reg :: "word5 ⇒ window_context" where
"emp_user_reg ws w5 ≡ 0"
definition emp_sys_reg :: "sys_context" where
"emp_sys_reg r ≡ 0"
definition emp_mem :: "mem_context" where
"emp_mem asi add ≡ None"
definition init_mmu:: "MMU_state" where
"init_mmu ≡ mmu_setup"
definition emp_cpu_cache :: "cpu_cache" where
"emp_cpu_cache ≡ ⦇dcache = empty_cache,icache = empty_cache⦈"
definition emp_dw_pool :: "delayed_write_pool" where
"emp_dw_pool ≡ []"
definition emp_bbyte :: "virtua_address ⇒ bool" where
"emp_bbyte add ≡ False"
definition emp_bword :: "virtua_address ⇒ bool" where
"emp_bword add ≡ False"
text ‹ANNUL = False, RESET_TRAP = False, EXECUTE_MODE = True,
RESET_MODE = False, ERROR_MODE = False.›
definition init_svar :: "sparc_state_var" where
"init_svar ≡ ⦇annul=False,resett=False,exe=True,
reset=False,err=False,ticc=(0b0000000::word7),
itrpt_lvl=(0b000::word3),st_bar=False,
atm_ldst_byte=emp_bbyte, atm_ldst_word=emp_bword⦈"
definition emp_trap :: "Trap set" where
"emp_trap ≡ {}"
definition emp_state :: "leon3_state" where
"emp_state ≡ ⦇cpu_reg=emp_cpu_reg, user_reg=emp_user_reg, sys_reg=emp_sys_reg,
mem=emp_mem, mmu=init_mmu, cache=emp_cpu_cache, dwrite=emp_dw_pool,
state_var=init_svar,
traps=emp_trap, undef=False⦈"
text ‹PSR.ET = 1, PS= 1, S = 1, in init_state.
By default, CWP = 0.
icc = 0000, ver = 0011, impl = 1111.
This is the default setting of LEON3.›
definition init_state0 :: "leon3_state" where
"init_state0 ≡
let s1 = cpu_reg_mod (0b11110011000000000000000011100000) PSR emp_state in
cpu_reg_mod (0b00000000000000000000000000000010) TBR s1"
text ‹Initialise PC and nPC.
And initialise r[14] in window 0 to 0x4ffffff0,
according to the LEON3 setup.›
definition init_state1 :: "leon3_state" where
"init_state1 ≡
let s1 = cpu_reg_mod (0b01000000000000000000000000000000) PC init_state0;
s2 = cpu_reg_mod (0b01000000000000000000000000000100) nPC s1
in
user_reg_mod (0x4ffffff0) 0 (14) s2
"
text ‹Initialise the memory address
0b01000000000000000000000000000000
and the following ones
with an example sequence of instructions.›
definition init_state2 :: "leon3_state" where
"init_state2 ≡
let s1 = mem_mod_w32 8 (0b01000000000000000000000000000000) (0b1111)
(0b11000110000000000100000101000010) init_state1;
s2 = mem_mod_w32 8 (0b01000000000000000000000000000100) (0b1111)
(0b11001000000000010100000101000110) s1;
s3 = mem_mod_w32 8 (0b01000000000000000000000000001000) (0b1111)
(0b10010000000000001100000000000100) s2;
s4 = mem_mod_w32 8 (0b01000000000000000000000000001100) (0b1111)
(0b11010000001000000100000101000010) s3;
s5 = mem_mod_w32 8 (0b01000000000000000000000000010000) (0b1111)
(0b11010010000000000100000101000010) s4
in
s5
"
definition init_state3:: "leon3_state" where
"init_state3 ≡
let curr_win = ucast (get_CWP (cpu_reg_val PSR init_state2));
s1 = user_reg_mod (0b01000000000000000000000000000000)
curr_win (0b00001) init_state2;
s2 = user_reg_mod (0b00000000000000000001000000000000)
curr_win (0b00010) s1;
s3 = user_reg_mod (0b01000000000000000000000000000000)
curr_win (0b00101) s2;
s4 = user_reg_mod (0b00000000000000000001000000000100)
curr_win (0b00110) s3;
s5 = mem_mod_w32 10 (0b01000000000000000001000000000000) (0b1111)
(0b00000000000000000000000000000010) s4;
s6 = mem_mod_w32 10 (0b01000000000000000001000000000100) (0b1111)
(0b00000000000000000000000000000100) s5
in
s6
"
end
Theory Sparc_Code_Gen
theory Sparc_Code_Gen
imports Main Sparc_Execution Sparc_Init_State
begin
export_code init_state0 reset_mode_mod reset_mode_val
state_undef
seq_exec_leon3 in OCaml
module_name Sparc_seq file ‹sparc_seq›
end